无法将名称解析为 (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?