Как определить два элемента с одинаковым именем с одинаковым типом в двух разных позициях в схеме

У меня есть сценарий, где у меня есть XML-схема с тем же именем элемента с тем же типом в двух разных позициях. Некоторые xml будут иметь элемент в первой позиции и несколько других xml имеют элемент во второй позиции.

   <xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
  <xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
  <xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit"/>

В моем xml некоторое время DisplayUnit идет выше последовательного и некоторое время после этого. Как я справляюсь с этим сценарием?

У меня есть еще одно разъяснение. В приведенном ниже сценарии элемент является не типом, а свойством. Позиция может быть выше или ниже выходного элемента, но происходит только один раз, как в первом сценарии.

<xs:element minOccurs="0" maxOccurs="0" name="MaxA" nillable="true" type="xs:unsignedInt" />
  <xs:element minOccurs="0" maxOccurs="0" name="Output" type="Output" />
  <xs:element minOccurs="0" maxOccurs="1" name="MaxA" nillable="true" type="xs:unsignedInt" />

Я искал много, но я не получил никакого решения.
Любая немедленная помощь в этом отношении приветствуется.

1 ответ

  1. Ваш вопрос состоит из двух частей: части XSD и части parser.

    XSD-файл

    Ваш XSD не подходит для результата, которого вы хотите достичь. Как написано, возможно, что DisplayUnitэлемент встречается дважды в документе. Есть два способа решить эту проблему, в зависимости от вашего сценария.

    Если элементы DisplayUnitи Serialявляются единственными элементами в последовательности или вся последовательность может быть в любом порядке, можно использовать <xs:all>вместо<xs:sequence>. <xs:all>позволяет элементам быть в любом порядке:

    <xs:all>
        <xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
        <xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
    </xs:all>
    

    Если этот вариант не подходит, поскольку предполагается, что другие элементы будут находиться в последовательности, можно заменить эту часть последовательности на <xs:choice>:

    <xs:choice>
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
            <xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
        </xs:sequence>
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
            <xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
        </xs:sequence>
    </xs:choice>
    

    Парсинг в C#

    После того, как вы исправили XSD и проверили документ, вы знаете, что существует ровно ноль или одно вхождение DisplayUnitи Serialтегов. Затем вы можете просто загрузить XML в XDocumentИли XmlDocument(если вы еще не сделали этого) и просто получить доступ к элементам по их имени (regardles порядка):

    //Assuming there is an XElement named parentElement
    XElement displayUnitElement = parentElement.Element("DisplayUnit");
    if (displayUnitElement != null) {
        //...
    }
    XElement serialElement = parentElement.Element("Serial");
    if (serialElement != null) {
        //...
    }
    

    На более сложных XML вы также можете использовать XPath. После проверки документа на XSD вы можете быть уверены в его структуре.