I'm trying to define a Schema which allows the use of specific (X)HTML elements in certain places. The problem that I'm facing is that the Schema fails compiling.
Here's the Schema:
<?xml version="1.0"?>
<xs:schema
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:import
namespace="http://www.w3.org/1999/xhtml"
schemaLocation="http://www.w3.org/MarkUp/Schema/xhtml11.xsd"
/>
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element
ref="html:blockquote"
minOccurs="0"
maxOccurs="unbounded"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
That's the XML file:
<foo xmlns:html="http://www.w3.org/1999/xhtml">
<html:blockquote>The quick brown fox jumped over the lazy dog.</html:blockquote>
</foo>
That's the error message that I get:
christian@armor01:~/testCase$ xmllint -schema foo.xsd -noout foo.xml
foo.xsd:12: element element: Schemas parser error : Element \
'{http://www.w3.org/2001/XMLSchema}element', attribute 'ref': The QName value \
'{http://www.w3.org/1999/xhtml}blockquote' does not resolve to a(n) element \
declaration.
WXS schema foo.xsd failed to compile
I understand what the error message means, but I do not understand why the error happens. The error message means that when I refer to blockquote, it cannot find blockquote. But I do not understand why this error happens since I'm importing the XHTML 1.1 schema.
I also tried to find out whether this is a problem specific to xmllint
. So I wrote a little Java program to perform the Schema validation, but I'm basically getting the same error.
Here's the Java program:
import java.io.*;
import java.net.*;
import javax.xml.*;
import javax.xml.parsers.*;
import javax.xml.validation.*;
import org.w3c.dom.*;
public class Validate {
public static void main(final String... args) throws Exception {
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//dbf.setValidating(true);
dbf.setSchema(schemaFactory.newSchema(new File(args[0]).toURI().toURL()));
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document doc = db.parse(args[1]);
}
}
Here's the error I'm getting from that program:
christian@armor01:~/testCase$ java Validate foo.xsd foo.xml
Exception in thread "main" org.xml.sax.SAXParseException; \
systemId: file:/home/christian/testCase/foo.xsd; \
lineNumber: 12; \
columnNumber: 88; \
src-resolve: Cannot resolve the name 'html:blockquote' to a(n) 'element declaration' component.
So clearly, I am doing something wrong in the Schema - but what? What is the correct way to define a Schema (for a target syntax without namespace) that reuses elements from another Schema/Namespace like XHTML?
BTW I also tried <xs:include/>
but that seemed inappropriate to me, and it failed because it requires that the including schema and the included schema target the same namespace.
It seems that the "blockquote" element is not defined as global element, thus you can not refer to it directly. If you have a look in the sub part of the xhtml schema http://www.w3.org/MarkUp/SCHEMA/xhtml11-model-1.xsd, you can notice that its type is
xhtml.blockquote.type
.So a workaround would be to declare your blockquote like so :
along with this valid XML instance:
You will notice that the blockquote element is not bound to the html namespace. Since you import other namespace's elements, I think also it would be a better practice to set a default target namespace to your own elements.