我有一个场景,我的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" />
我搜索了很多,但我没有得到任何解决方案。 在这方面的任何直接帮助表示赞赏。
答案 0 :(得分:0)
您的问题包含两部分:XSD部分和解析器部分。
<强> 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
(如果您还没有这样做),只需按名称(订单的顺序)访问元素:
//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进行验证,您就可以确定其结构。