无法将名称解析为 (n) 'type definition' 组件
Cannot resolve the name to a(n) 'type definition' component
我不知道还能做什么:
Caused by: org.xml.sax.SAXParseException; lineNumber: 22; columnNumber: 74; src-resolve: Cannot resolve the name 'head:BusinessApplicationHeader1' to a(n) 'type definition' component.
代码:
private val schemaLang: String = javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI
private val xsdFileSource: BufferedSource = Source.fromResource("main.xsd")
private val xsdStream = new javax.xml.transform.stream.StreamSource(xsdFileSource.reader())
private val schema: Schema = javax.xml.validation.SchemaFactory.newInstance(schemaLang).newSchema(xsdStream)
private val factory: SAXParserFactory = javax.xml.parsers.SAXParserFactory.newInstance()
factory.setNamespaceAware(true)
factory.setValidating(true)
factory.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true)
factory.setSchema(schema)
private val validatingParser: SAXParser = factory.newSAXParser()
main.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:head="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"
xmlns:sw2="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.03"
xmlns:sw4="urn:iso:std:iso:20022:tech:xsd:pacs.004.001.02"
xmlns:sw8="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02"
xmlns:sw28="urn:iso:std:iso:20022:tech:xsd:pacs.028.001.01"
xmlns:ca29="urn:iso:std:iso:20022:tech:xsd:camt.029.001.03"
xmlns:ca56="urn:iso:std:iso:20022:tech:xsd:camt.056.001.01"
xmlns="urn:montran:message.01" targetNamespace="urn:montran:message.01" elementFormDefault="qualified">
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:camt.029.001.03" schemaLocation="camt.029.001.03.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:camt.056.001.01" schemaLocation="camt.056.001.01.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.004.001.02" schemaLocation="pacs.004.001.02.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.03" schemaLocation="pacs.002.001.03.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02" schemaLocation="pacs.008.001.02.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.028.001.01" schemaLocation="pacs.028.001.01.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:head.001.001.01" schemaLocation="head.001.001.01.xsd" />
<xs:element name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="AppHdr" type="head:BusinessApplicationHeader1"/>
<!-- other stuff not included -->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
head.001.001.01.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
<xs:include schemaLocation="common.xsd"/>
<xs:element name="AppHdr" type="BusinessApplicationHeader1"/>
<xs:complexType name="BusinessApplicationHeader1">
<xs:sequence>
<xs:element name="CharSet" type="UnicodeChartsCode" minOccurs="0"/>
<xs:element name="Fr" type="Party9Choice"/>
<xs:element name="To" type="Party9Choice"/>
<xs:element name="BizMsgIdr" type="Max35TextReference"/>
<xs:element name="MsgDefIdr" type="Max35Text"/>
<xs:element name="BizSvc" type="Max35Text" minOccurs="0"/>
<xs:element name="CreDt" type="ISONormalisedDateTime"/>
<xs:element name="CpyDplct" type="CopyDuplicate1Code" minOccurs="0"/>
<xs:element name="PssblDplct" type="TrueFalseIndicator" minOccurs="0"/>
<xs:element name="Prty" type="BusinessMessagePriorityCode" minOccurs="0"/>
<xs:element name="Sgntr" type="SignatureEnvelope" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<!-- other stuff removed -->
</xs:schema>
找到解决方案:
如果
A.xsd imports B.xsd which imports C.xsd
那么显然我们必须以相反的顺序加载模式
javax.xml.validation.SchemaFactory.newInstance(schemaLang).newSchema(Array(C.xsd, B.xsd, A.xsd))
此外,这会停止使用包含(相对于导入)
所以解决方案是加载 xsd 不是作为流而是作为 URL
private val schema: Schema = javax.xml.validation.SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(
this.getClass.getClassLoader.getResource("main.xsd")
)
相关:
How to validate an XML file using Java with an XSD having an include?
Parsing Schema in Java With imports and includes?
我不知道还能做什么:
Caused by: org.xml.sax.SAXParseException; lineNumber: 22; columnNumber: 74; src-resolve: Cannot resolve the name 'head:BusinessApplicationHeader1' to a(n) 'type definition' component.
代码:
private val schemaLang: String = javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI
private val xsdFileSource: BufferedSource = Source.fromResource("main.xsd")
private val xsdStream = new javax.xml.transform.stream.StreamSource(xsdFileSource.reader())
private val schema: Schema = javax.xml.validation.SchemaFactory.newInstance(schemaLang).newSchema(xsdStream)
private val factory: SAXParserFactory = javax.xml.parsers.SAXParserFactory.newInstance()
factory.setNamespaceAware(true)
factory.setValidating(true)
factory.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true)
factory.setSchema(schema)
private val validatingParser: SAXParser = factory.newSAXParser()
main.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:head="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"
xmlns:sw2="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.03"
xmlns:sw4="urn:iso:std:iso:20022:tech:xsd:pacs.004.001.02"
xmlns:sw8="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02"
xmlns:sw28="urn:iso:std:iso:20022:tech:xsd:pacs.028.001.01"
xmlns:ca29="urn:iso:std:iso:20022:tech:xsd:camt.029.001.03"
xmlns:ca56="urn:iso:std:iso:20022:tech:xsd:camt.056.001.01"
xmlns="urn:montran:message.01" targetNamespace="urn:montran:message.01" elementFormDefault="qualified">
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:camt.029.001.03" schemaLocation="camt.029.001.03.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:camt.056.001.01" schemaLocation="camt.056.001.01.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.004.001.02" schemaLocation="pacs.004.001.02.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.03" schemaLocation="pacs.002.001.03.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02" schemaLocation="pacs.008.001.02.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:pacs.028.001.01" schemaLocation="pacs.028.001.01.xsd" />
<xs:import namespace="urn:iso:std:iso:20022:tech:xsd:head.001.001.01" schemaLocation="head.001.001.01.xsd" />
<xs:element name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="AppHdr" type="head:BusinessApplicationHeader1"/>
<!-- other stuff not included -->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
head.001.001.01.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
<xs:include schemaLocation="common.xsd"/>
<xs:element name="AppHdr" type="BusinessApplicationHeader1"/>
<xs:complexType name="BusinessApplicationHeader1">
<xs:sequence>
<xs:element name="CharSet" type="UnicodeChartsCode" minOccurs="0"/>
<xs:element name="Fr" type="Party9Choice"/>
<xs:element name="To" type="Party9Choice"/>
<xs:element name="BizMsgIdr" type="Max35TextReference"/>
<xs:element name="MsgDefIdr" type="Max35Text"/>
<xs:element name="BizSvc" type="Max35Text" minOccurs="0"/>
<xs:element name="CreDt" type="ISONormalisedDateTime"/>
<xs:element name="CpyDplct" type="CopyDuplicate1Code" minOccurs="0"/>
<xs:element name="PssblDplct" type="TrueFalseIndicator" minOccurs="0"/>
<xs:element name="Prty" type="BusinessMessagePriorityCode" minOccurs="0"/>
<xs:element name="Sgntr" type="SignatureEnvelope" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<!-- other stuff removed -->
</xs:schema>
找到解决方案:
如果
A.xsd imports B.xsd which imports C.xsd
那么显然我们必须以相反的顺序加载模式
javax.xml.validation.SchemaFactory.newInstance(schemaLang).newSchema(Array(C.xsd, B.xsd, A.xsd))
此外,这会停止使用包含(相对于导入)
所以解决方案是加载 xsd 不是作为流而是作为 URL
private val schema: Schema = javax.xml.validation.SchemaFactory .newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema( this.getClass.getClassLoader.getResource("main.xsd") )
相关:
How to validate an XML file using Java with an XSD having an include?
Parsing Schema in Java With imports and includes?