尝试使用一系列半有序的强制和可选元素验证 XML 架构时收到错误
Receiving an error when trying to validate XML Schema with a sequence of semi-ordered compulsary and optional elements
我在根据具有可选元素的嵌套序列的 XSD 验证 XML 时遇到问题。 This question 与 3 年前的类似,但不幸的是没有解决我的问题。举个例子 XML:
<root>
<a>...</a>
<b>...</b>
<c>...</c>
<b>...</b>
<c>...</c>
<d>...</d>
<d>...</d>
<b>...</b>
<c>...</c>
<d>...</d>
<END>...</END>
</root>
和我对应的XSD:
<xs:schema ...>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="aType"/>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="b" type="bType"/>
<xs:element name="c" type="cType"/>
<xs:element name="d" minOccurs="0" maxOccurs="3" type="dType"/>
</xs:sequence>
<xs:element name="END" type="eType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
换句话说:
- "a" 必须出现一次,后面跟着:
- 由"b"、"c"和"d"依次组成的嵌套序列。但是,"d" 是可选的,最多可以出现 3 次。
- 最后,"END" 必须出现一次。
这些类型是架构中别处定义的复杂类型。
XSD 逻辑上代表了我想做但不起作用的事情。它似乎是有效的 XSD(解析器在读取 XSD 时不会出错)。但是我收到的错误让我相信我没有正确构建它。
这是我的 JavaScript/Java 代码,用于在构建 DOM 时针对 XSD 验证 XML(使用 Rhino JavaScript 引擎,所以这看起来很奇怪):
var schemaReader = Packages.java.io.StringReader(schemaString);
var schemaSource = Packages.javax.xml.transform.stream.StreamSource(schemaReader);
var schemaFactory = Packages.javax.xml.validation.SchemaFactory.newInstance(Packages.javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
var schema = schemaFactory.newSchema(schemaSource);
var dbf = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setSchema(schema);
var db = dbf.newDocumentBuilder();
db.setErrorHandler(myErrorHandler);
var xmlReader2 = Packages.java.io.StringReader(xmlString);
var xmlInputSource = Packages.org.xml.sax.InputSource(xmlReader2);
xmlDoc = db.parse(xmlInputSource);
但我收到这样的错误:
Error: cvc-complex-type.2.4.d: Invalid content was found starting with element 'd.10'. No child element is expected at this point.
其中 d.10 是 "d" 类型的最后一个子元素。
我认为我构建的 XSD 不正确 - 任何人都可以建议替代方法吗?
看起来你的代码是正确的,所以问题出在你的输入文件上。我拿了你的 XSD 并修改了它(但保留了完整的结构):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="aType"/>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="b" type="aType"/>
<xs:element name="c" type="aType"/>
<xs:element name="d" minOccurs="0" maxOccurs="3" type="aType"/>
</xs:sequence>
<xs:element name="END" type="aType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="aType">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
下面的XML符合你解释的逻辑,它有效:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xsd-choice-and%20occurrence.xsd">
<a></a>
<b></b>
<c></c>
<b></b>
<c></c>
<b></b>
<c></c>
<d></d>
<d></d>
<d></d>
<b></b>
<c></c>
<d></d>
<d></d>
<d></d>
<END></END>
</root>
d
个元素可以是 0 到 3 之间的任意值。
我在根据具有可选元素的嵌套序列的 XSD 验证 XML 时遇到问题。 This question 与 3 年前的类似,但不幸的是没有解决我的问题。举个例子 XML:
<root>
<a>...</a>
<b>...</b>
<c>...</c>
<b>...</b>
<c>...</c>
<d>...</d>
<d>...</d>
<b>...</b>
<c>...</c>
<d>...</d>
<END>...</END>
</root>
和我对应的XSD:
<xs:schema ...>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="aType"/>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="b" type="bType"/>
<xs:element name="c" type="cType"/>
<xs:element name="d" minOccurs="0" maxOccurs="3" type="dType"/>
</xs:sequence>
<xs:element name="END" type="eType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
换句话说:
- "a" 必须出现一次,后面跟着:
- 由"b"、"c"和"d"依次组成的嵌套序列。但是,"d" 是可选的,最多可以出现 3 次。
- 最后,"END" 必须出现一次。
这些类型是架构中别处定义的复杂类型。
XSD 逻辑上代表了我想做但不起作用的事情。它似乎是有效的 XSD(解析器在读取 XSD 时不会出错)。但是我收到的错误让我相信我没有正确构建它。
这是我的 JavaScript/Java 代码,用于在构建 DOM 时针对 XSD 验证 XML(使用 Rhino JavaScript 引擎,所以这看起来很奇怪):
var schemaReader = Packages.java.io.StringReader(schemaString);
var schemaSource = Packages.javax.xml.transform.stream.StreamSource(schemaReader);
var schemaFactory = Packages.javax.xml.validation.SchemaFactory.newInstance(Packages.javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
var schema = schemaFactory.newSchema(schemaSource);
var dbf = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setSchema(schema);
var db = dbf.newDocumentBuilder();
db.setErrorHandler(myErrorHandler);
var xmlReader2 = Packages.java.io.StringReader(xmlString);
var xmlInputSource = Packages.org.xml.sax.InputSource(xmlReader2);
xmlDoc = db.parse(xmlInputSource);
但我收到这样的错误:
Error: cvc-complex-type.2.4.d: Invalid content was found starting with element 'd.10'. No child element is expected at this point.
其中 d.10 是 "d" 类型的最后一个子元素。
我认为我构建的 XSD 不正确 - 任何人都可以建议替代方法吗?
看起来你的代码是正确的,所以问题出在你的输入文件上。我拿了你的 XSD 并修改了它(但保留了完整的结构):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="aType"/>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="b" type="aType"/>
<xs:element name="c" type="aType"/>
<xs:element name="d" minOccurs="0" maxOccurs="3" type="aType"/>
</xs:sequence>
<xs:element name="END" type="aType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="aType">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
下面的XML符合你解释的逻辑,它有效:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xsd-choice-and%20occurrence.xsd">
<a></a>
<b></b>
<c></c>
<b></b>
<c></c>
<b></b>
<c></c>
<d></d>
<d></d>
<d></d>
<b></b>
<c></c>
<d></d>
<d></d>
<d></d>
<END></END>
</root>
d
个元素可以是 0 到 3 之间的任意值。