Question

I need to create XML file compliant to a complex XSD file. My approach is to validate step by step (using TDD) every type on the XSD. I can only validate root elements, so what I am doing is

  • Create a new schema, on the same namespace, with only a root element called "TestNode" of the target complex type to test
  • Add the schema to the schema validation list

So, this a part of the original complex schema

<?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>

I want to create and validate XML nodes with "AComplexTypeFormat" format, but I can't validate 'OriginalElement' because it's not a root element.

I am not allowed to modify the original XSD file. Thus, my workaround is create an accesory NodeTester XSD file:

<?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>

And then add BOTH schemas to the validation list

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()) { }

When I validate the stringXML that contains the XML node, I receive an error (sorry, translating from spanish):

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

Cryptic :( 'MsgID' is not allowed because the validator is waiting for... 'MsgID'

What is wrong? Is this correct (adding another scheme to list), or there is another way to merge elements of the same namespace coming from different files to make a validation?

Thanks!

Was it helpful?

Solution

Finally, I have found another workaround: not add new schemas, but EDIT THE SCHEME

So, If I need to test if a XML fragment(node) is compilant to a particular XSD type, I just edit the schema and add a ROOT element of the type to test, with the name of the XML fragment root element.

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);
}

In my new, compiled in memory schema, the element is now root and I can validate it correctly :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top