如何使用 XML 模式重用来自另一个模式/命名空间(即 XHTML)的元素?
How to reuse elements from another Schema / Namespace (i.e. XHTML) with XML Schema?
我正在尝试定义一个允许在特定位置使用特定 (X)HTML 元素的架构。我面临的问题是架构编译失败。
这是架构:
<?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>
那是 XML 文件:
<foo xmlns:html="http://www.w3.org/1999/xhtml">
<html:blockquote>The quick brown fox jumped over the lazy dog.</html:blockquote>
</foo>
这是我收到的错误消息:
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
我明白错误信息的意思,但我不明白为什么会出现错误。错误消息意味着当我引用 blockquote 时,它找不到 blockquote。但我不明白为什么会发生此错误,因为我正在导入 XHTML 1.1 架构。
我也试图找出这是否是 xmllint
特有的问题。所以我写了一个 Java 程序来执行模式验证,但我基本上得到了同样的错误。
这是 Java 程序:
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]);
}
}
这是我从该程序中得到的错误:
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.
很明显,我在架构中做错了什么 - 但是什么? 定义重用来自另一个 Schema/Namespace 的元素(如 XHTML)的架构(对于没有命名空间的目标语法)的正确方法是什么?
顺便说一句,我也尝试过 <xs:include/>
,但这对我来说似乎不合适,并且失败了,因为它要求包含模式和包含模式以相同的命名空间为目标。
好像"blockquote"元素没有定义为全局元素,所以不能直接引用。
如果您查看 xhtml 模式 http://www.w3.org/MarkUp/SCHEMA/xhtml11-model-1.xsd 的子部分,您会注意到它的类型是 xhtml.blockquote.type
.
因此,解决方法是像这样声明块引用:
<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 name="blockquote" type="html:xhtml.blockquote.type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
连同这个有效的 XML 实例:
<?xml version="1.0"?>
<foo xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
<blockquote><html:p>quick brown fox jumped over the lazy dog.</html:p></blockquote>
</foo>
您会注意到 blockquote 元素未绑定到 html 命名空间。
由于您导入了其他命名空间的元素,我认为将默认目标命名空间设置为您自己的元素也是更好的做法。
我正在尝试定义一个允许在特定位置使用特定 (X)HTML 元素的架构。我面临的问题是架构编译失败。
这是架构:
<?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>
那是 XML 文件:
<foo xmlns:html="http://www.w3.org/1999/xhtml">
<html:blockquote>The quick brown fox jumped over the lazy dog.</html:blockquote>
</foo>
这是我收到的错误消息:
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
我明白错误信息的意思,但我不明白为什么会出现错误。错误消息意味着当我引用 blockquote 时,它找不到 blockquote。但我不明白为什么会发生此错误,因为我正在导入 XHTML 1.1 架构。
我也试图找出这是否是 xmllint
特有的问题。所以我写了一个 Java 程序来执行模式验证,但我基本上得到了同样的错误。
这是 Java 程序:
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]);
}
}
这是我从该程序中得到的错误:
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.
很明显,我在架构中做错了什么 - 但是什么? 定义重用来自另一个 Schema/Namespace 的元素(如 XHTML)的架构(对于没有命名空间的目标语法)的正确方法是什么?
顺便说一句,我也尝试过 <xs:include/>
,但这对我来说似乎不合适,并且失败了,因为它要求包含模式和包含模式以相同的命名空间为目标。
好像"blockquote"元素没有定义为全局元素,所以不能直接引用。
如果您查看 xhtml 模式 http://www.w3.org/MarkUp/SCHEMA/xhtml11-model-1.xsd 的子部分,您会注意到它的类型是 xhtml.blockquote.type
.
因此,解决方法是像这样声明块引用:
<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 name="blockquote" type="html:xhtml.blockquote.type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
连同这个有效的 XML 实例:
<?xml version="1.0"?>
<foo xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
<blockquote><html:p>quick brown fox jumped over the lazy dog.</html:p></blockquote>
</foo>
您会注意到 blockquote 元素未绑定到 html 命名空间。 由于您导入了其他命名空间的元素,我认为将默认目标命名空间设置为您自己的元素也是更好的做法。