在 JAXB 中是否可以在解组期间仅验证一个xsd:any元素并且不再钻取?
用例是我有两个 XML Schema 文件,一个定义信封(在某些时候包括一个xsd:any元素),另一个定义有效负载模式(用于xsd:any元素)。由于实际上可能有许多不同类型的有效负载 - 未来还会有更多 - 我已经构建了我的代码以使用两步解组,如对这个 SO question的回答中所建议的那样。
所以我有一个库,它只在不查看有效负载的情况下解组和验证信封。问题是使用 JAXB 我无法想出一种方法来仅setSchema
使用Unmarshaller
. 验证失败,因为它找不到有效负载的模式,但我无法在信封处理jar中添加这些模式,因为信封应该与有效负载无关。因此,我无法以与有效负载无关的方式在其自己的库中实现信封处理逻辑。
下面是一个最小的具体示例。当代码运行时,它会失败并显示:
[java] Caused by: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 23; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'b:person'.
信封 - A.XSD
<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
xmlns ="http://www.w3.org/2001/XMLSchema"
xmlns:a ="http://www.example.org/A"
targetNamespace ="http://www.example.org/A">
<element name="someType" type="a:SomeType"></element>
<complexType name="SomeType">
<sequence>
<any namespace="##other" processContents="strict"/>
</sequence>
</complexType>
</schema>
有效载荷 - B.XSD
<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
xmlns ="http://www.w3.org/2001/XMLSchema"
xmlns:b ="http://www.example.org/B"
targetNamespace="http://www.example.org/B"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element name="person" type="b:PersonType"></element>
<complexType name="PersonType">
<sequence>
<element name="firstName" type="string"/>
<element name="lastName" type="string"/>
</sequence>
</complexType>
</schema>
XML 实例 - ab.xml
<?xml version="1.0" encoding="UTF-8"?>
<a:someType xmlns:a="http://www.example.org/A"
xmlns:b="http://www.example.org/B"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/A A.xsd
http://www.example.org/B B.xsd">
<b:person>
<b:firstName>Mary</b:firstName>
<b:lastName>Bones</b:lastName>
</b:person>
</a:someType>
JAXB 代码
public static void main (String args[]) throws JAXBException, FileNotFoundException, SAXException {
final Schema SCHEMA_A = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new File("A.xsd"));
JAXBContext jc = JAXBContext.newInstance("example.a");
Unmarshaller u = jc.createUnmarshaller();
u.setSchema(SCHEMA_A);
JAXBElement<SomeType> element = (JAXBElement<SomeType>) u.unmarshal( new FileInputStream( "ab.xml" ) );
}