使用前缀时,C#验证针对XSD的简单XML不起作用

时间:2016-12-16 17:22:00

标签: c# xml xsd

我正在尝试使用C#中的XSD验证XML文件:

C#代码:

XmlReaderSettings booksSettings = new XmlReaderSettings();
XmlSchema xs = booksSettings.Schemas.Add("urn.mota:ndd.acu.gisae.VicuSolution111", "validation.xsd");
booksSettings.ValidationType = ValidationType.Schema;
booksSettings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
booksSettings.ValidationEventHandler += new ValidationEventHandler(valEventHandler);
XmlReader books = XmlReader.Create("data.xml", booksSettings);
while (books.Read()) {  }
Console.ReadLine();

data.xml中:

<VicuSolution111 xmlns:ns0="urn.mota:ndd.acu.gisae.VicuSolution111">
  <ns0:Header>
      <ns0:TransactionType></ns0:TransactionType>
  </ns0:Header>
</VicuSolution111>

validation.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="urn.mota:ndd.acu.gisae.VicuSolution111"
           elementFormDefault="qualified">
  <xs:element name="VicuSolution111">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" name="Header">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="1" maxOccurs="1" name="TransactionType">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:minLength value="1"/>
                    <xs:maxLength value="40"/>
                  </xs:restriction>
                </xs:simpleType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

当我使用ReportValidationWarnings执行验证时,我收到以下消息:

Warning Could not find schema information for the element 'VicuSolution111'.
Warning Could not find schema information for the element 'urn.mota:ndd.acu.gisae.VicuSolution111:Header'.
Warning Could not find schema information for the element 'urn.mota:ndd.acu.gisae.VicuSolution111:TransactionType'.

但是由于空的TransactionType节点,我希望得到一个错误。如果我通过添加xmlns="urn.mota:ndd.acu.gisae.VicuSolution111"而没有ns0前缀来修改data.xml,则验证可以正常工作。

<VicuSolution111 xmlns:ns0="urn.mota:ndd.acu.gisae.VicuSolution111"
                 xmlns="urn.mota:ndd.acu.gisae.VicuSolution111">
  <ns0:Header>
    <ns0:TransactionType></ns0:TransactionType>
  </ns0:Header>
</VicuSolution111>

这给出了预期的消息:

Error: The 'urn.mota:ndd.acu.gisae.VicuSolution111:TransactionType' element is invalid - The value '' is invalid according to its datatype 'String' - The actual length is less than the MinLength value.

有谁知道为什么会这样,以及如何在不修改原始XML文件和保留xmlns的情况下验证文档:ns0?

1 个答案:

答案 0 :(得分:2)

首先,你的架构没有targetnamespace,如果你改变它,那么它主要起作用,即

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Liquid Studio - Data Designer Edition 15.0.0.6978 (https://www.liquid-technologies.com)-->
<xs:schema xmlns="urn.mota:ndd.acu.gisae.VicuSolution111" 
           elementFormDefault="qualified" 
           targetNamespace="urn.mota:ndd.acu.gisae.VicuSolution111" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="VicuSolution111">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Header" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="TransactionType" minOccurs="1" maxOccurs="1">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1" />
                                        <xs:maxLength value="40" />
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

但是你的XML是错误的,如果你像这样修改它会起作用

<?xml version="1.0" encoding="utf-8" ?>
<ns0:VicuSolution111  xmlns:ns0="urn.mota:ndd.acu.gisae.VicuSolution111">
  <ns0:Header>
    <ns0:TransactionType></ns0:TransactionType>
  </ns0:Header>
</ns0:VicuSolution111>

如果原始XML是您想要的输出,那么您需要将模式分解为2个文件,一个包含没有targetnamespace的VicuSolution111,另一个包含Header,其targetnamespace设置为'urn.mota:ndd.acu.gisae.VicuSolution111 ”。

很明显,解析器找不到VicuSolution111(在xml文件中没有命名空间)的模式定义的原因是因为你告诉解析器模式代表命名空间'urn.mota:ndd.acu中的项。 gisae.VicuSolution111' 。

    XmlSchema xs = booksSettings.Schemas.Add("urn.mota:ndd.acu.gisae.VicuSolution111", "validation.xsd");