我想针对包含断言的 xsd 1.1 文件测试生成的 xml 文件,并且我想在 Java 中执行此操作。
我的xml内容是
<?xml version="1.0" encoding="UTF-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="person.xsd">
<Name>John Doe</Name>
<Age>17</Age>
</Person>
xsd内容如下,包含两个断言
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Age" type="xs:integer"/>
</xs:sequence>
<xs:assert test="Age >= 18"/>
<xs:assert test="(string-length(Name) > 15)"/>
</xs:complexType>
</xs:element>
</xs:schema>
我用
implementation("org.opengis.cite.xerces:xercesImpl-xsd11:2.12-beta-r1667115")
作为我的
build.gradle.kts
文件中的依赖项。以下 Java 代码有效:
// That's the important String which instantiates a xsd 1.1 aware schema factory + validator
SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
Schema s = sf.newSchema(new StreamSource(getClass().getResourceAsStream(xsdFilePath)));
Validator v = s.newValidator();
v.validate(new StreamSource(getClass().getResourceAsStream(xmlFilePath)));
万岁,现在我收到验证异常:
Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 10; cvc-assertion: Assertion evaluation ('Age >= 18') for element 'Person' on schema type '#AnonType_Person' did not succeed.
当我将年龄修正为 18 岁时,我不会收到有关名称的验证错误(长度 > 15),但我得到
Exception in thread "main" java.lang.NoClassDefFoundError: com/ibm/icu/text/UTF16
at org.eclipse.wst.xml.xpath2.processor.internal.function.FnStringLength.string_length(FnStringLength.java:105)
at org.eclipse.wst.xml.xpath2.processor.internal.function.FnStringLength.evaluate(FnStringLength.java:74)
at org.eclipse.wst.xml.xpath2.processor.DefaultDynamicContext.evaluate_function(DefaultDynamicContext.java:194)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1611)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.FunctionCall.accept(FunctionCall.java:46)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:2139)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.FilterExpr.accept(FilterExpr.java:52)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1258)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathExpr.accept(XPathExpr.java:43)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.do_bin_args(DefaultEvaluator.java:803)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:614)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.CmpExpr.accept(CmpExpr.java:106)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.do_expr(DefaultEvaluator.java:315)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1573)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.ParExpr.accept(ParExpr.java:40)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:2139)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.FilterExpr.accept(FilterExpr.java:52)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1258)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathExpr.accept(XPathExpr.java:43)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1607)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.FunctionCall.accept(FunctionCall.java:46)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:2139)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.FilterExpr.accept(FilterExpr.java:52)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:1258)
at org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathExpr.accept(XPathExpr.java:43)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.do_expr(DefaultEvaluator.java:315)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.visit(DefaultEvaluator.java:336)
at org.eclipse.wst.xml.xpath2.processor.ast.XPath.accept(XPath.java:43)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.evaluate(DefaultEvaluator.java:290)
at org.apache.xerces.impl.xs.AbstractPsychoPathXPath2Impl.evaluateXPathExpr(Unknown Source)
at org.apache.xerces.impl.xs.XMLAssertPsychopathXPath2Impl.evaluateOneAssertion(Unknown Source)
at org.apache.xerces.impl.xs.XMLAssertPsychopathXPath2Impl.evaluateAssertionsFromAComplexType(Unknown Source)
at org.apache.xerces.impl.xs.XMLAssertPsychopathXPath2Impl.processAllAssertionsOnElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLAssertPsychopathXPath2Impl.endElement(Unknown Source)
at org.apache.xerces.impl.xs.XSDAssertionValidator.handleEndElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.assertionValidatorEndElementDelegate(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.jaxp.validation.StreamValidatorHelper.validate(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at java.xml/javax.xml.validation.Validator.validate(Validator.java:124)
at org.example.HelloWorld.validateXMLSchemaXerxes(HelloWorld.java:50)
at org.example.HelloWorld.main(HelloWorld.java:31)
Caused by: java.lang.ClassNotFoundException: com.ibm.icu.text.UTF16
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
... 48 more
它显然失败了,因为它期望 ICU4J 位于类路径上,但找不到它。
不,没有其他可用的开源实现。 (我花了大约一年的时间在 Saxon-EE 中编写(商业)模式处理器,所以这并不奇怪。)