使用 C# 进行 XML 验证

时间:2021-05-11 06:13:41

标签: c# xml xsd xsd-validation xml-validation

大家好! 我在尝试根据其架构验证 XML 文件时遇到一些问题。 我拥有的 XML 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<game:gameXML xmlns:game="national:game" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header>
    <From description="Gamer">Gamer</From>
    <To description="Player">Player</To>
    <MessageId>1620711716</MessageId>
    <MessageDate>2021-05-11T15:41:53</MessageDate>
    <TransactionGroup>Ball</TransactionGroup>
    <Priority>Medium</Priority>
    <SecurityContext>CONTACT_PERSON_GOES_HERE</SecurityContext>
    <Market>Japan</Market>
  </Header>
  <Transactions>
    <Transaction transaction="1620711716">
      <ReportRequest>
        <ReportParameters xsi:type="game:reportParameters">
          <ReportName>All</ReportName>
          <FromDate>2005-01-01</FromDate>
          <ToDate>2021-05-11</ToDate>    
        </ReportParameters>
      </ReportRequest>
    </Transaction>
  </Transactions>
</game:gameXML>

我使用 VS 2019 生成了相应的架构,结果如下:

xmlFile.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:game="national:game" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="national:game" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:import schemaLocation="xmlContent.xsd" />
    <xs:element name="gameXML">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Header" />
                <xs:element ref="Transactions" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

xmlContent.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Header">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="From">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="description" type="xs:string" use="required" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
                <xs:element name="To">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="description" type="xs:string" use="required" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
                <xs:element name="MessageId" type="xs:unsignedInt" />
                <xs:element name="MessageDate" type="xs:dateTime" />
                <xs:element name="TransactionGroup" type="xs:string" />
                <xs:element name="Priority" type="xs:string" />
                <xs:element name="SecurityContext" type="xs:string" />
                <xs:element name="Market" type="xs:string" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Transactions">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Transaction">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="ReportRequest">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="ReportParameters">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element name="ReportName" type="xs:string" />
                                                    <xs:element name="FromDate" type="xs:date" />
                                                    <xs:element name="ToDate" type="xs:date" />
                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:attribute name="transaction" type="xs:unsignedInt" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我用来加载这些的代码是:

XmlReaderSettings settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
XmlSchemaSet xs = new XmlSchemaSet();
xs.Add("national:game", "xmlFile.xsd");
xs.Add("national:game", "xmlContent.xsd");
xs.Compile();

一旦我运行它,它就会因错误而爆炸:

System.Exception: This is an invalid xsi:type 'national:game:reportParameters'.

很明显,它正在将命名空间注入 xmlContent.xsd 文件,我无法弄清楚需要设置什么来防止这种情况发生。事实上,这个 .xsd 文件应该有它自己的命名空间(参见实际 .xml 文件中的 <ReportParameters xsi:type="game:reportParameters">)。

任何线索、指示或帮助将不胜感激。 谢谢。

1 个答案:

答案 0 :(得分:0)

您的所有类型均未命名,因此除了架构内置类型之外,似乎没有 xsi:type 的有效值,因为所有 complexType 都是匿名的。

这是 xsd.exe(用于生成架构的工具)受限的一方面,因为根据定义,如果存在 xsi:type 属性,它必须引用架构声明的某种类型,但生成的架构声明没有命名类型。然而,它的目的是解决歧义,因此同样的工具引入歧义是不合逻辑的。

要解决此问题,请重构 xmlContent.xsd 以在全局范围内声明 reportParameters 类型并引用它,即

<xs:element name="ReportParameters" type="game:reportParameters"/>

<xs:complexType name="reportParameters">
...
相关问题