抽象的
在我目前正在進行的專案中,我有多個模塊,每個模塊都定義一個 XSD 檔案。加載配置時,我計劃以編程方式定位這些 XSD 檔案,然后使用驗證配置SchemaFactory.newSchema(Source[]),例如
public void validate(Document document, InputStream... schemas) throws Exception {
Source[] sources = new Source[schemas.length];
for (int i = 0; i < schemas.length; i ) {
sources[i] = new StreamSource(schemas[i]);
}
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(sources);
schema.newValidator().validate(new DOMSource(document.getDocumentElement()));
}
到目前為止,我一直關注這個Stack Overflow 帖子,但為了使用上述方法,我認為我需要使用不同的命名空間來構建參考。
生成的架構包含來自指定來源的組件。如果使用 schemaLocation 和命名空間的適當值將所有這些源匯入到具有不同 targetNamespace 且沒有其自己的組件的單個模式檔案中,如果匯入元素以與源相同的順序給出,則將獲得相同的結果.
測驗
使用core.xsd我定義了配置的靜態結構。
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:core="http://web.com/core"
targetNamespace="http://web.com/core">
<xsd:element name="configuration" type="core:configuration" />
<xsd:complexType name="configuration">
<xsd:sequence>
<!-- other elements -->
<xsd:element maxOccurs="unbounded" name="agent" type="core:agent" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="agent">
<xsd:sequence>
<!-- other elements -->
<xsd:element ref="core:agentImpl" />
</xsd:sequence>
<!-- attributes -->
</xsd:complexType>
<xsd:element name="agentImpl" type="core:agentImpl" />
<xsd:complexType name="agentImpl" abstract="true" />
</xsd:schema>
使用ext.xsd我在agent. 在此示例中,我使用一個 XSD 檔案添加了兩個代理,但稍后,應將此類代理定義分成多個ext-*.xsd檔案。
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:core="http://web.com/core"
xmlns:ext="http://web.com/ext"
targetNamespace="http://web.com/ext">
<xsd:import namespace="http://web.com/core" schemaLocation="core.xsd" />
<xsd:element name="file-mover" type="ext:file-mover" substitutionGroup="core:agentImpl" />
<xsd:complexType name="file-mover">
<xsd:complexContent>
<xsd:extension base="core:agentImpl">
<!-- implementation-specific stuff -->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="junction" type="ext:junction" substitutionGroup="core:agentImpl" />
<xsd:complexType name="junction">
<xsd:complexContent>
<xsd:extension base="core:agentImpl">
<!-- implementation-specific stuff -->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
但是,當使用
@Test
void singleExtension() throws Exception {
try (InputStream docIn = getClass().getResourceAsStream("configuration.xml");
InputStream coreIn = getClass().getResourceAsStream("core.xsd");
InputStream extIn = getClass().getResourceAsStream("ext.xsd")) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new StreamSource(docIn));
validate(document, coreIn, extIn);
}
}
和configuration.xml
<?xml version="1.0" encoding="UTF-8"?>
<core:configuration xmlns:core="http://web.com/core" xmlns:ext="http://web.com/ext">
<agent>
<ext:file-mover />
</agent>
<agent>
<ext:junction />
</agent>
</core:configuration>
我明白了
org.xml.sax.SAXParseException; cvc-elt.1.a: Cannot find the declaration of element 'core:configuration'.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:135)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:284)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2132)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:829)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.beginNode(DOMValidatorHelper.java:276)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:243)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:189)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:108)
at java.xml/javax.xml.validation.Validator.validate(Validator.java:124)
at com.spell.moreen.core.xsd.so.StackOverflowTest.validate(StackOverflowTest.java:27)
at com.spell.moreen.core.xsd.so.StackOverflowTest.singleExtension(StackOverflowTest.java:38)
... (only jupiter stuff from here on)
結論
我在 Stack Overflow 上找到的關于這個特定例外的帖子都解決了一些命名空間宣告錯誤加上一個未宣告根元素但僅宣告其型別的實體。
如果我添加xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"and xsi:schemaLocation="http://web.com/core core.xsd http://web.com/ext ext.xsd",configuration.xmleclipse 可以很好地驗證它,所以我假設命名空間是正確的。
根元素存在于<xsd:element name="configuration" type="core:configuration" />in 中core.xsd,它總是通過系結xmlns:core="...",所以我也看不出有什么問題。
我忽略或理解錯了什么?
uj5u.com熱心網友回復:
為了使用命名空間驗證 XML,必須在決議 XML 時考慮到命名空間。在這里,這意味著DocumentBuilderFactory必須設定為知道命名空間。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // default is 'false'
否則我猜決議器只是忽略了這些資訊,這反過來又使它們對模式驗證器不可用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/525016.html
標籤:爪哇xmlxsd
上一篇:命名空間元素的正確XPath?
