簡體   English   中英

如何使用XSD驗證XML?

[英]How do I validate XML using XSD?

我犯了一個錯誤,但我看不出它是什么...

我正在嘗試使用Java針對XSD驗證一段XML(SOAP消息)。 我認為應該是有效的帶有異常的XML /消息片段失敗了:

org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'tns:Envelope'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203).

注意1:我已經調試了xmlSource和xsdSource,它們包含具有預期字符串的預期Readers。

注2:XML的內容不能更改。 我只是一個消費者。

注意3:由於XML是SOAP消息,所以我從Web上獲取了XSD。 因此,這可能是不正確的。

注意4:為簡化起見,我簡化了傳入消息,但與“實際”消息卻得到相同的錯誤。

爪哇

@Override
public boolean isMessageValid(final String xml) {
    try {
        final Source xmlSource = getStreamSource(xml);
        final Source xsdSource = getStreamSource(fileService.getResourceFileAsString("xsd/soap-envelope.xsd"));

        final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        final Schema schema = schemaFactory.newSchema(xsdSource);
        final Validator validator = schema.newValidator();
        validator.validate(xmlSource);
        return true;
    } catch (final Exception ex) {
        LOG.error("Exception whilst validating message", ex);
        return false;
    }
}

private StreamSource getStreamSource(final String xml) {
    return new StreamSource(new StringReader(xml));
}

XML格式

<?xml version="1.0" encoding="UTF-8"?>
<tns:Envelope xsi:schemaLocation="http://www.w3.org/2001/12/soap-envelope soap-envelope.xsd"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.w3.org/2001/12/soap-envelope">
    <tns:Body>
        <!-- snipped -->
        <someThing>else</someThing>
    </tns:Body>
</tns:Envelope>

XSD

<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"
           targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" >


    <!-- Envelope, header and body -->
    <xs:element name="Envelope" type="tns:Envelope" />
    <xs:complexType name="Envelope" >
        <xs:sequence>
            <xs:element ref="tns:Header" minOccurs="0" />
            <xs:element ref="tns:Body" minOccurs="1" />
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
        </xs:sequence>
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:element name="Header" type="tns:Header" />
    <xs:complexType name="Header" >
        <xs:sequence>
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
        </xs:sequence>
        <xs:anyAttribute namespace="##other" processContents="lax" />
    </xs:complexType>

    <xs:element name="Body" type="tns:Body" />
    <xs:complexType name="Body" >
        <xs:sequence>
            <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
        </xs:sequence>
        <xs:anyAttribute namespace="##any" processContents="lax" >
            <xs:annotation>
                <xs:documentation>
                    Prose in the spec does not specify that attributes are allowed on the Body element
                </xs:documentation>
            </xs:annotation>
        </xs:anyAttribute>
    </xs:complexType>


    <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them.  -->
    <xs:attribute name="mustUnderstand" >
        <xs:simpleType>
            <xs:restriction base='xs:boolean'>
                <xs:pattern value='0|1' />
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="actor" type="xs:anyURI" />

    <xs:simpleType name="encodingStyle" >
        <xs:annotation>
            <xs:documentation>
                'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
            </xs:documentation>
        </xs:annotation>
        <xs:list itemType="xs:anyURI" />
    </xs:simpleType>

    <xs:attribute name="encodingStyle" type="tns:encodingStyle" />
    <xs:attributeGroup name="encodingStyle" >
        <xs:attribute ref="tns:encodingStyle" />
    </xs:attributeGroup>

    <xs:element name="Fault" type="tns:Fault" />
    <xs:complexType name="Fault" final="extension" >
        <xs:annotation>
            <xs:documentation>
                Fault reporting structure
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="faultcode" type="xs:QName" />
            <xs:element name="faultstring" type="xs:string" />
            <xs:element name="faultactor" type="xs:anyURI" minOccurs="0" />
            <xs:element name="detail" type="tns:detail" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="detail">
        <xs:sequence>
            <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
        </xs:sequence>
        <xs:anyAttribute namespace="##any" processContents="lax" />
    </xs:complexType>

</xs:schema>

我認為我已經點了點頭。

提前致謝

前綴“ tns”綁定到源和模式中的不同名稱空間。 因此,這不是源文檔詞匯表的架構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM