使用模式进行XML验证

时间:2016-08-03 07:34:33

标签: xml xsd xml-parsing

我有这个xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--20160722121507-600701340-->
    <Envelope xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">
       <Header>
          <Action>http://tempuri.org/SalesOrder_AXService/create</Action>
       </Header>
       <Body>
          <MessageParts>
             <SalesOrder_AX>
                <SenderId>AX</SenderId>
                <SalesOrderHeaderAIF class="entity">
                   <DeliveryMode>1</DeliveryMode>
                   <ExternalSalesId>600701340</ExternalSalesId>
                   <InventLocationId>126</InventLocationId>
                   <Obs />
                   <PaymMode />
                   <SalesAmount>27.5</SalesAmount>
                   <SalesOrderDate>2016-07-22 15:12:25</SalesOrderDate>
                   <SalesOriginId>TestOrigin</SalesOriginId>
                   <SalesTaker />
                   <TaxGroup>Grp</TaxGroup>
                   <SalesOrderLinesAIF class="entity">
                      <DeliveryMode>1</DeliveryMode>
                      <ExternalSalesId>600701340</ExternalSalesId>
                      <ExternalSalesLineId>2</ExternalSalesLineId>
                      <InventLocationId>126</InventLocationId>
                      <ItemId>TestItemId</ItemId>
                      <LineAmount>27.5</LineAmount>
                      <LineDisc>27.49</LineDisc>
                      <SalesOrderedQty>1</SalesOrderedQty>
                      <SalesOriginId>TestOrigin</SalesOriginId>
                      <SalesPrice>54.99</SalesPrice>
                      <TaxItemGroup>1</TaxItemGroup>
                      <WorkerSalesResponsible />
                   </SalesOrderLinesAIF>
                   <SalesOrderCustomersAIF class="entity">
                      <City />
                      <CountryRegionId>CID</CountryRegionId>
                      <County />
                      <CustAccount>312751</CustAccount>
                      <CustGroup>CL_INT</CustGroup>
                      <CustName>Test Cust Name</CustName>
                      <DlvCity />
                      <DlvCountryRegionId>CID</DlvCountryRegionId>
                      <DlvCounty />
                      <DlvState>ST</DlvState>
                      <DlvStreet />
                      <Email>xxx@yyy.zz</Email>
                      <InvName />
                      <Phone>111111111</Phone>
                      <SalesOriginId>TestOrigin</SalesOriginId>
                      <Street />
                      <TaxGroup>Grp</TaxGroup>
                   </SalesOrderCustomersAIF>
                </SalesOrderHeaderAIF>
             </SalesOrder_AX>
          </MessageParts>
       </Body>
    </Envelope>

我正在使用此架构验证它:

        <?xml version="1.0" encoding="utf-8"?>
        <xsd:schema targetNamespace="http://schemas.microsoft.com/dynamics/2011/01/documents/Message" 
                    xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message" 
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                    elementFormDefault="qualified">

            <xsd:element name="Envelope" type="EnvelopeType"/>
            <xsd:element name="MessageParts" type="MessagePartsType"/>

            <xsd:complexType name="EnvelopeType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Envelope of the message.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="Header" type="HeaderType"/>
                    <xsd:element name="Body" type="BodyType"/>
                </xsd:sequence> 
            </xsd:complexType>

            <xsd:complexType name="HeaderType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Header containing message metadata.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>          
                    <xsd:element name="MessageId" type="xsd:string" minOccurs="0"/>
                    <xsd:element name="SourceEndpointUser" type="xsd:string" minOccurs="0"/>
                    <xsd:element name="SourceEndpoint" type="xsd:string" minOccurs="0"/>
                    <xsd:element name="DestinationEndpoint" type="xsd:string" minOccurs="0"/>
                    <xsd:element name="Action" type="xsd:string"/>
                    <xsd:element name="RequestMessageId" type="xsd:string" minOccurs="0"/>
                </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="BodyType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Body of the message.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="MessageParts" type="MessagePartsType"/>
                </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="MessagePartsType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Zero or more parts of the message.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="SalesOrder_ax" type="SalesOrder_axType"/>
                </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="SalesOrder_axType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Body of the message.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="SenderId" type="xsd:string"/>
                    <xsd:element name="SalesOrderHeaderAIF" type="SalesOrderHeaderAIFType"/>
                </xsd:sequence>
            </xsd:complexType>

            <xsd:complexType name="SalesOrderHeaderAIFType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Zero or more parts of the sales order header.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="DeliveryMode" type="xsd:string"/>
                    <xsd:element name="ExternalSalesId" type="xsd:string"/>
                    <xsd:element name="InventLocationId" type="xsd:string"/>
                    <xsd:element name="Obs" type="xsd:string"/>
                    <xsd:element name="PaymMode" type="xsd:string"/>
                    <xsd:element name="SalesAmount" type="xsd:string"/>
                    <xsd:element name="SalesOrderDate" type="xsd:string"/>
                    <xsd:element name="SalesOriginId" type="xsd:string"/>
                    <xsd:element name="SalesTaker" type="xsd:string"/>
                    <xsd:element name="TaxGroup" type="xsd:string"/>
                    <xsd:element name="SalesOrderLinesAIF" type="SalesOrderLinesAIFType"/>
                    <xsd:element name="SalesOrderCustomersAIF" type="SalesOrderCustomersAIFType"/>
                </xsd:sequence>
                <xsd:attribute id="class" name="class">
                   <xsd:simpleType>
                      <xsd:restriction base="classType" />
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:complexType>

            <xsd:complexType name="SalesOrderLinesAIFType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Zero or more parts of the sales order line.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="DeliveryMode" type="xsd:string"/>
                    <xsd:element name="ExternalSalesId" type="xsd:string"/>
                    <xsd:element name="ExternalSalesLineId" type="xsd:string"/>
                    <xsd:element name="InventLocationId" type="xsd:string"/>
                    <xsd:element name="ItemId" type="xsd:string"/>
                    <xsd:element name="LineAmount" type="xsd:string"/>
                    <xsd:element name="LineDisc" type="xsd:string"/>
                    <xsd:element name="SalesOrderedQty" type="xsd:string"/>
                    <xsd:element name="SalesOriginId" type="xsd:string"/>
                    <xsd:element name="SalesPrice" type="xsd:string"/>
                    <xsd:element name="TaxItemGroup" type="xsd:string"/>
                    <xsd:element name="WorkerSalesResponsible" type="xsd:string"/>
                </xsd:sequence>

                <xsd:attribute name="class">
                   <xsd:simpleType>
                      <xsd:restriction base="classType" />
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:complexType>

            <xsd:complexType name="SalesOrderCustomersAIFType">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en-us">Zero or more parts of the customer instance.</xsd:documentation>
                </xsd:annotation>
                <xsd:sequence>
                    <xsd:element name="City" type="xsd:string"/>
                    <xsd:element name="CountryRegionId" type="xsd:string"/>
                    <xsd:element name="County" type="xsd:string"/>
                    <xsd:element name="CustAccount">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:minLength value="1"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:element>
                    <xsd:element name="CustGroup" type="xsd:string"/>
                    <xsd:element name="CustName" type="xsd:string"/>
                    <xsd:element name="DlvCity" type="xsd:string"/>
                    <xsd:element name="DlvCountryRegionId" type="xsd:string"/>
                    <xsd:element name="DlvCounty" type="xsd:string"/>
                    <xsd:element name="DlvState" type="xsd:string"/>
                    <xsd:element name="DlvStreet" type="xsd:string"/>
                    <xsd:element name="Email" type="xsd:string"/>
                    <xsd:element name="InvName" type="xsd:string"/>
                    <xsd:element name="Phone" type="xsd:string"/>
                    <xsd:element name="SalesOriginId" type="xsd:string"/>
                    <xsd:element name="Street" type="xsd:string"/>
                    <xsd:element name="TaxGroup" type="xsd:string"/>
                </xsd:sequence>

                <xsd:attribute name="class">
                   <xsd:simpleType>
                      <xsd:restriction base="classType" />
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:complexType>

            <xsd:simpleType id="classType" name="classType">
               <xsd:restriction base="xsd:string">
                  <xsd:maxLength value="70" />
               </xsd:restriction>
            </xsd:simpleType>
        </xsd:schema>

在我向xml中的SalesOrder_AX元素添加命名空间之前,这一切都很好用:

 xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX"

从这一刻起,我收到以下错误:

 The element 'MessageParts' in namespace 'http://schemas.microsoft.com/dynamics/2011/01/documents/Message' has invalid child element 'SalesOrder_AX' in namespace 'http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX'. List of possible elements expected: 'SalesOrder_AX' in namespace 'http://schemas.microsoft.com/dynamics/2011/01/documents/Message'.

我真的无法弄清楚我应该如何解决这个问题。它从一开始就存在,但我摆脱了它,以便能够完全生成模式。

现在生成了架构,甚至我不明白为什么,该命名空间必须在那里..

使用原始xml文件进行更新:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--20160722121507-600701340-->
    <Envelope xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">
       <Header>
          <Action>http://tempuri.org/SalesOrder_AXService/create</Action>
       </Header>
       <Body>
          <MessageParts>
             <SalesOrder_ATXN xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX">
                <SenderId>AX</SenderId>
                <SalesOrderHeaderAIF class="entity">
                   <DeliveryMode>1</DeliveryMode>
                   <ExternalSalesId>600701340</ExternalSalesId>
                   <InventLocationId>126</InventLocationId>
                   <Obs />
                   <PaymMode />
                   <SalesAmount>27.5</SalesAmount>
                   <SalesOrderDate>2016-07-22 15:12:25</SalesOrderDate>
                   <SalesOriginId>TestOrigin</SalesOriginId>
                   <SalesTaker />
                   <TaxGroup>Grp</TaxGroup>
                   <SalesOrderLinesAIF class="entity">
                      <DeliveryMode>1</DeliveryMode>
                      <ExternalSalesId>600701340</ExternalSalesId>
                      <ExternalSalesLineId>2</ExternalSalesLineId>
                      <InventLocationId>126</InventLocationId>
                      <ItemId>TestItemId</ItemId>
                      <LineAmount>27.5</LineAmount>
                      <LineDisc>27.49</LineDisc>
                      <SalesOrderedQty>1</SalesOrderedQty>
                      <SalesOriginId>TestOrigin</SalesOriginId>
                      <SalesPrice>54.99</SalesPrice>
                      <TaxItemGroup>1</TaxItemGroup>
                      <WorkerSalesResponsible />
                   </SalesOrderLinesAIF>
                   <SalesOrderCustomersAIF class="entity">
                      <City />
                      <CountryRegionId>CID</CountryRegionId>
                      <County />
                      <CustAccount>312751</CustAccount>
                      <CustGroup>CL_INT</CustGroup>
                      <CustName>Test Cust Name</CustName>
                      <DlvCity />
                      <DlvCountryRegionId>CID</DlvCountryRegionId>
                      <DlvCounty />
                      <DlvState>ST</DlvState>
                      <DlvStreet />
                      <Email>xxx@yyy.zz</Email>
                      <InvName />
                      <Phone>111111111</Phone>
                      <SalesOriginId>TestOrigin</SalesOriginId>
                      <Street />
                      <TaxGroup>Grp</TaxGroup>
                   </SalesOrderCustomersAIF>
                </SalesOrderHeaderAIF>
             </SalesOrder_ATXN>
          </MessageParts>
       </Body>
    </Envelope>

1 个答案:

答案 0 :(得分:1)

  

在我向xml中的SalesOrder_AX元素添加命名空间之前,这一切都很好用:   xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX"

添加默认命名空间会有效地更改元素的名称及其子项的名称。看到对有效性的影响,你不应该感到惊讶。

顺便说一句,你的陈述引出了一个问题,即如果它真的&#34;一切都很好,直到我添加命名空间,&#34;你为什么要添加命名空间?

无论如何,您的错误消息表明SalesOrder_AX不应该在

http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX

命名空间,而不是

http://schemas.microsoft.com/dynamics/2011/01/documents/Message

因此,将SalesOrder_AX放入请求的命名空间而不是您选择的命名空间。

更新

OP已经澄清说他喜欢XSD,可以成功验证他的固定XML。

需要两个XSD - 每个命名空间一个:

基础XSD:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://schemas.microsoft.com/dynamics/2011/01/documents/Message" 
            xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message" 
            xmlns:s="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX" 
            elementFormDefault="qualified">

  <xsd:import namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX"
              schemaLocation="SalesOrder_AX.xsd"/>

  <xsd:element name="Envelope" type="EnvelopeType"/>
  <xsd:element name="MessageParts" type="MessagePartsType"/>

  <xsd:complexType name="EnvelopeType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Envelope of the message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="Header" type="HeaderType"/>
      <xsd:element name="Body" type="BodyType"/>
    </xsd:sequence> 
  </xsd:complexType>

  <xsd:complexType name="HeaderType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Header containing message metadata.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>          
      <xsd:element name="MessageId" type="xsd:string" minOccurs="0"/>
      <xsd:element name="SourceEndpointUser" type="xsd:string" minOccurs="0"/>
      <xsd:element name="SourceEndpoint" type="xsd:string" minOccurs="0"/>
      <xsd:element name="DestinationEndpoint" type="xsd:string" minOccurs="0"/>
      <xsd:element name="Action" type="xsd:string"/>
      <xsd:element name="RequestMessageId" type="xsd:string" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="BodyType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Body of the message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="MessageParts" type="MessagePartsType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="MessagePartsType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Zero or more parts of the message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element ref="s:SalesOrder_ATXN"/>
    </xsd:sequence>
  </xsd:complexType>

</xsd:schema>

<强> SalesOrder_AX.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns:s="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX" 
            elementFormDefault="qualified"
            targetNamespace="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder_AX">


  <xsd:element name="SalesOrder_ATXN" type="s:SalesOrder_axType"/>

  <xsd:complexType name="SalesOrder_axType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Body of the message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="SenderId" type="xsd:string"/>
      <xsd:element name="SalesOrderHeaderAIF" type="s:SalesOrderHeaderAIFType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="SalesOrderHeaderAIFType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Zero or more parts of the sales order header.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="DeliveryMode" type="xsd:string"/>
      <xsd:element name="ExternalSalesId" type="xsd:string"/>
      <xsd:element name="InventLocationId" type="xsd:string"/>
      <xsd:element name="Obs" type="xsd:string"/>
      <xsd:element name="PaymMode" type="xsd:string"/>
      <xsd:element name="SalesAmount" type="xsd:string"/>
      <xsd:element name="SalesOrderDate" type="xsd:string"/>
      <xsd:element name="SalesOriginId" type="xsd:string"/>
      <xsd:element name="SalesTaker" type="xsd:string"/>
      <xsd:element name="TaxGroup" type="xsd:string"/>
      <xsd:element name="SalesOrderLinesAIF" type="s:SalesOrderLinesAIFType"/>
      <xsd:element name="SalesOrderCustomersAIF" type="s:SalesOrderCustomersAIFType"/>
    </xsd:sequence>
    <xsd:attribute id="class" name="class">
      <xsd:simpleType>
        <xsd:restriction base="s:classType" />
      </xsd:simpleType>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:complexType name="SalesOrderLinesAIFType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Zero or more parts of the sales order line.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="DeliveryMode" type="xsd:string"/>
      <xsd:element name="ExternalSalesId" type="xsd:string"/>
      <xsd:element name="ExternalSalesLineId" type="xsd:string"/>
      <xsd:element name="InventLocationId" type="xsd:string"/>
      <xsd:element name="ItemId" type="xsd:string"/>
      <xsd:element name="LineAmount" type="xsd:string"/>
      <xsd:element name="LineDisc" type="xsd:string"/>
      <xsd:element name="SalesOrderedQty" type="xsd:string"/>
      <xsd:element name="SalesOriginId" type="xsd:string"/>
      <xsd:element name="SalesPrice" type="xsd:string"/>
      <xsd:element name="TaxItemGroup" type="xsd:string"/>
      <xsd:element name="WorkerSalesResponsible" type="xsd:string"/>
    </xsd:sequence>

    <xsd:attribute name="class">
      <xsd:simpleType>
        <xsd:restriction base="s:classType" />
      </xsd:simpleType>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:complexType name="SalesOrderCustomersAIFType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en-us">Zero or more parts of the customer instance.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="City" type="xsd:string"/>
      <xsd:element name="CountryRegionId" type="xsd:string"/>
      <xsd:element name="County" type="xsd:string"/>
      <xsd:element name="CustAccount">
        <xsd:simpleType>
          <xsd:restriction base="xsd:string">
            <xsd:minLength value="1"/>
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
      <xsd:element name="CustGroup" type="xsd:string"/>
      <xsd:element name="CustName" type="xsd:string"/>
      <xsd:element name="DlvCity" type="xsd:string"/>
      <xsd:element name="DlvCountryRegionId" type="xsd:string"/>
      <xsd:element name="DlvCounty" type="xsd:string"/>
      <xsd:element name="DlvState" type="xsd:string"/>
      <xsd:element name="DlvStreet" type="xsd:string"/>
      <xsd:element name="Email" type="xsd:string"/>
      <xsd:element name="InvName" type="xsd:string"/>
      <xsd:element name="Phone" type="xsd:string"/>
      <xsd:element name="SalesOriginId" type="xsd:string"/>
      <xsd:element name="Street" type="xsd:string"/>
      <xsd:element name="TaxGroup" type="xsd:string"/>
    </xsd:sequence>

    <xsd:attribute name="class">
      <xsd:simpleType>
        <xsd:restriction base="s:classType" />
      </xsd:simpleType>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:simpleType id="classType" name="classType">
    <xsd:restriction base="xsd:string">
      <xsd:maxLength value="70" />
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>