简体   繁体   中英

How to validate multiple elements with same name but with different types

I'm trying to validate an XML against an XSD that has duplicate elements with different types. But Can't get this to work.

XML

<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
    <Notification>
        <sObject xmlns:sf="urn:sobject.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Tracking">
            <sf:Id>a2L1g000000OzM7EAK</sf:Id>
        </sObject>
        <sObject xmlns:sf="urn:sobject.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Log">
            <sf:Id>a1t1g000001wMQrAAM</sf:Id>
        </sObject>
    </Notification>
</notifications>

As you can see in the above sObject element is occurring twice. Following is the XSD I have comeupwith.

Main XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:ob="http://soap.sforce.com/2005/09/outbound" xmlns:sf="urn:sobject.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://soap.sforce.com/2005/09/outbound" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="schema1.xsd" namespace="urn:sobject.soap.sforce.com" />
  <xs:element name="notifications">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Notification">
         <xs:complexType>
            <xs:sequence>
              <xs:element name="sObject" maxOccurs="unbounded" type="ob:Tracking" />
              <!--xs:element name="sObject" type="ob:Log"/-->
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="Tracking">
    <xs:sequence>
        <xs:element ref="sf:Id" />
    </xs:sequence>
    <xs:anyAttribute processContents="skip"/>
  </xs:complexType>
  <xs:complexType name="Log">
    <xs:sequence>
        <xs:element ref="sf:Id" />
    </xs:sequence>
    <xs:anyAttribute processContents="skip"/>
  </xs:complexType>
</xs:schema>

Dependent schema1.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:sobject.soap.sforce.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Id" type="xs:string" />
</xs:schema>

Note: I can't change the XML structure as it is coming from an external system and this is a minimal reproducible sample and the actual XML is pretty complex.

The trick is to define a base type sObjectType as the supertype of Log and Tracking . I defined it as an abstract type because it would make no sense to actually have an element using it.

This seems to work for me:

Notifications.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    targetNamespace="http://soap.sforce.com/2005/09/outbound"
    attributeFormDefault="unqualified" elementFormDefault="qualified"

    xmlns:not="http://soap.sforce.com/2005/09/outbound" 
    xmlns:sobj="urn:sobject.soap.sforce.com">

    <xs:import schemaLocation="schema1.xsd" namespace="urn:sobject.soap.sforce.com" />

    <xs:element name="notifications">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Notification">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="sObject" maxOccurs="unbounded"
                                type="not:sObjectAbstractType" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="sObjectAbstractType" abstract="true" />

    <xs:complexType name="Tracking">
        <xs:complexContent>
            <xs:extension base="not:sObjectAbstractType">
                <xs:sequence>
                    <xs:element ref="sobj:Id" />
                </xs:sequence>
                <xs:anyAttribute processContents="skip" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="Log">
        <xs:complexContent>
            <xs:extension base="not:sObjectAbstractType">
                <xs:sequence>
                    <xs:element ref="sobj:Id" />
                </xs:sequence>
                <xs:anyAttribute processContents="skip" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM