使用附件XSD文件针对模式验证XML节点

时间:2013-10-10 15:25:02

标签: c# xml-validation

我需要创建符合复杂XSD文件的XML文件。我的方法是逐步验证(使用TDD)XSD上的每个类型。我只能验证根元素,所以我正在做的是

  • 在同一名称空间中创建一个新模式,只有一个名为“TestNode”的根元素用于测试目标复杂类型
  • 将架构添加到架构验证列表

所以,这是原始复杂模式的一部分

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="urn:FooSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:FooSchema">
    <xs:element name="Document" type="Document"/>
    <xs:complexType name="AComplexType">
        <xs:sequence>
            <xs:element name="MsgId" type="Max35Text"/>
            ...
    </xs:complexType>
    ...
        ...
        <xs:element name="OriginalElement" type="AComplexType"/>
        ...
    ...
</xs:schema>

我想用“AComplexTypeFormat”格式创建和验证XML节点,但我无法验证'OriginalElement',因为它不是根元素。

我不允许修改原始XSD文件。因此,我的解决方法是创建一个附件NodeTester XSD文件:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element xmlns="urn:FooSchema" name="TestNode" type="AComplexType" />
</xs:schema>

然后将BOTH模式添加到验证列表

XmlSchema originalSchema = XmlSchema.Read(new StreamReader("ComplexSchema.xsd"), XMLValidationEventHandler);
XmlSchema testingSchema = XmlSchema.Read(new StreamReader("NodeTester.xsd"), XMLValidationEventHandler);        
XmlReaderSettings validatorSettings = new XmlReaderSettings();
validatorSettings.Schemas.Add(originalSchema);
validatorSettings.Schemas.Add(testingSchema);
validatorSettings.ValidationType = ValidationType.Schema;
validatorSettings.ConformanceLevel = ConformanceLevel.Fragment;
validatorSettings.ValidationEventHandler += new ValidationEventHandler(XMLValidationEventHandler);

 XmlReader validationReader = XmlReader.Create(new StringReader(stringXML), validatorSettings);
 while (validationReader.Read()) { }

当我验证包含XML节点的stringXML时,我收到错误(抱歉,从西班牙语翻译):

The element 'TestNode' has a secondary element 'MsgId' not valid. Expected list of possible elements: 'MsgId' in the namespace 'urn:FooSchema'.

Cryptic :('MsgID'是不被允许的,因为验证器正在等待...'MsgID'

有什么问题?这是正确的(添加另一个方案列表),还是有另一种方法来合并来自不同文件的同一命名空间的元素进行验证?

谢谢!

1 个答案:

答案 0 :(得分:0)

最后,我找到了另一种解决方法:不添加新模式,但编辑方案

所以,如果我需要测试XML片段(节点)是否与特定的XSD类型兼容,我只需编辑模式并添加要测试的类型的ROOT元素,并使用XML片段根元素的名称

public static void AddElementToSchema(XmlSchema xmlSchema, string elementName, string elementType, string xmlNamespace)
{
    XmlSchemaElement testNode = new XmlSchemaElement();
    testNode.Name = elementName;
    testNode.Namespaces.Add("", xmlNamespace);
    testNode.SchemaTypeName = new XmlQualifiedName(elementType, xmlNamespace);
    xmlSchema.Items.Add(testNode);
    xmlSchema.Compile(XMLValidationEventHandler);
}

在我的新编译的内存模式中,元素现在是root,我可以正确验证它:)