如何使用命名空间来验证XML

时间:2013-09-25 15:29:40

标签: c# xml validation xsd

我正在尝试了解如何验证包含多个命名空间的XML文档,而不是走得太远。作为我正在做的事情的简化示例,我在一个命名空间中定义了一个“root”元素,如下所示:

文件:“root.xsd”

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="root"/>
    <xs:element name="root">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="root">
                    <xs:sequence>
                        <xs:element ref="allowedChild"/>
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="allowedChild"/>
    <xs:element name="allowedChild" type="allowedChild"/>
</xs:schema>

然后像这样定义一个“child”元素:

文件:“child.xsd”

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:include schemaLocation="root.xsd"/>
    <xs:complexType name="child">
        <xs:complexContent>
            <xs:extension base="allowedChild"/>
        </xs:complexContent>
    </xs:complexType>
    <xs:element name="child" type="child" substitutionGroup="allowedChild"/>
</xs:schema>

我想要验证的xml应该是这样的:

<root xmlns="root.xsd">
    <child xmlns="child.xsd"/>
</root>

如果我尝试在XmlSpy中验证这一点,我得到“无法在此文档实例中找到对支持的模式类型(DTD,W3C模式)的引用。”。

我还尝试编写一些C#来验证(这是我的最终目标)。我的代码如下所示:

static void Main(string[] args)
{
    using (var stream = new StreamReader("Example.xml"))
    {
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.ValidationEventHandler += MyValidationEventHandler;
        schemaSet.XmlResolver = new XmlUrlResolver();

        schemaSet.Add(null, "root.xsd");

        XmlReaderSettings settings = new XmlReaderSettings()
        {
            ValidationType = ValidationType.Schema,
            ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings,
            Schemas = schemaSet,
        };

        settings.ValidationEventHandler += MyValidationEventHandler;

        XmlReader reader = XmlReader.Create(stream, settings);
        while (reader.Read())
        {
        }
    }
}

static void MyValidationEventHandler(object sender, ValidationEventArgs e)
{
}

但是这给了我以下验证错误:

Could not find schema information for the element 'root.xsd:root'.
Could not find schema information for the element 'child.xsd:child'.

我希望XmlUrlResolver会找到xsd文件(保存在同一个文件夹中),但我猜它不会这样做???

我的目标是拥有多个child.xsd类型文件,这些文件在编译时生成并仅在运行时解析。这可能吗?

1 个答案:

答案 0 :(得分:1)

你需要这样的东西:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" 
    attributeFormDefault="unqualified" 
    targetNamespace="http://root.schemas.mycompany.com">

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" 
    attributeFormDefault="unqualified" 
    targetNamespace="http://child.schemas.mycompany.com">

<root xmlns="http://root.schemas.mycompany.com">
    <child xmlns="http://child.schemas.mycompany.com"/>
</root>

您将XSD文件名视为命名空间名称,这是不正确的。此外,由于您未使用targetNamespace,因此您的XML类型和元素根本不属于任何命名空间。