Reputation: 49
I'm trying to figure out how to validate XML against a schema in C#. If the XML is simple and uses no namespace elements everything seems to go great. But, if it uses XML namespaces, I start to run into problems.
The XML I want to produce is:
<?xml version="1.0" encoding="utf-8"?>
<SlideDeck xmlns:xy="http://something.com" xy:type="SlideDefinitions">
<Slide>...</Slide>
<Slide>...</Slide>
...
</SlideDeck>
I can produce this in C# with something equivalent to:
XmlDocument xDoc = new XmlDocument();
XmlElement xSlideDeck = xDoc.CreateElement("SlideDeck");
xDoc.AppendChild(xSlideDeck);
xSlideDeck.SetAttribute("xmlns:xy", "http://something.com");
xSlideDeck.SetAttribute("type", "http://something.com", "SlideDefinitions");
And I can attempt to validate the produced XML document with this:
xDoc.Schemas.Add("", "Schema.xsd");
xDoc.Validate(Handler);
The Schema.xsd file to validate against is fairly simply right now:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="SlideDeck">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Slide"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
... Slide Defined Here ...
</xs:schema>
When running the validation, I get the following errors:
The 'http://something.com:type' attribute is not declared.
The required attribute 'type' is missing.
I've also tried adding an additional schema to the XmlDocument that references http://something.com with the same schema file (hoping that it would pull that in for the 'xy' namespace). I've also tried adding just a schema to the proper uri (leaving out the schema with no uri), but depending on other settings, nothing is validated. I've tried making the root 'SlideDeck' element belong to the http://something.com namespace as well.
Any idea what might be happening here? I can't change the format of the XML document coming out much at all. I can make the 'SlideDeck' elements prefixed with 'xy', along with all the other elements, but I'd prefer not to have to modify all the code to additionally add the uri to the namespace and prefix to make that happen. The big sticking points are the xmlns:xy definition and the xy:type attribute which alert the recipient to what to expect. Other changes are reasonable. I can also control the XSD the program validates against as well if getting it to create and validate would best be accomplished by changes there.
Upvotes: 2
Views: 1761
Reputation: 11983
Your schema says that the SlideDeck
element must have a type
attribute - both in the null namespace, whereas in your XML the SlideDeck
element has an attribute type
in the http://something.com
namespace - hence the errors.
You should change the XML to:
<SlideDeck type="SlideDefinitions">
<Slide>. . . </Slide>
<Slide>. . . </Slide>
. . .
</SlideDeck>
(i.e. get rid of the namespace).
In alternative you have to change the schema, splitting it into two:
typeAttr.xsd:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xy="http://something.com"
xmlns="http://something.com"
targetNamespace="http://something.com"
elementFormDefault="qualified"
attributeFormDefault="qualified" >
<xs:attribute name="type" type="xs:string" />
</xs:schema>
slide.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xy="http://something.com">
<xs:import namespace="http://something.com" schemaLocation="typeAttr.xsd"/>
<xs:element name="SlideDeck">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Slide"/>
</xs:choice>
</xs:sequence>
<xs:attribute ref="xy:type" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Slide"></xs:element>
</xs:schema>
(in the same directory).
In this way you define the type
attribute in its separate namespace, and the original XML validates correctly.
Upvotes: 1