Reputation: 327
I was attempting to validate a group of XML tags that I have with an xsd file that I created, with the added constraint that all XElement
's must belong to a namespace.
<xs:schema id="TestSchema"
targetNamespace="http://test.org/test.xsd"
xmlns="http://test.org/test.xsd"
xmlns:mstns="http://test.org/test.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="testRoot">
<xs:complexType>
<xs:sequence>
<xs:element name="testObject">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" />
<xs:element name="bar" />
</xs:sequence>
<xs:attribute name="testType" type="xs:int" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
/xs:schema>
... where the XML that I start with appears as follows:
<testRoot>
<testObject testType="2">
<foo />
<bar />
</testObject>
</testRoot>
Any problems that may stem from the syntax of the element declarations is because this is simplified; interestingly, the XML validates against this schema when I don't bother trying to add namespaces to the elements.
Once the XML is parsed into LINQ to XML, I add namespaces to each element with an extension method:
public static void SetDefaultXmlNamespace(this XElement element, XNamespace ns)
{
foreach (var item in element.DescendantsAndSelf())
{
item.Name = ns.GetName(item.Name.LocalName);
}
}
But my attempts to validate this schema are unsuccessful. Attempting to create and validate against the above XML yields a cryptic error:
The element 'testRoot' in namespace 'http://test.org/test.xsd' has invalid child element 'testObject' in namespace 'http://test.org/test.xsd'. List of possible elements expected: 'testObject'.
I would expect such a simple example to succeed, but I'm clearly missing something.
I attempt the validation by converting the XElement tree in question into an XDocument and then validating:
string xsdMarkup = "schema here";
XElement testRoot; // declared elsewhere
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(AppStateXmlMapper.SchemaNamespace, XmlReader.Create(new StringReader(xsdMarkup)));
XDocument xmlDoc = new XDocument(testRoot);
xmlDoc.Root.SetDefaultXmlNamespace(AppStateXmlMapper.Ns);
List<string> errorList = new List<string>();
// attempt validation
xmlDoc.Validate(schemas, (sender, args) =>
{
errorList.Add(args.Message);
});
It's probably worth noting that I've tried adding constraints to the schema such as the elementFormDefault= "qualified"
and attributeFormDefault="qualified"
tag, but that simply changes the validation errors to other elements/attributes. I tried adding a namespace to every single attribute on the fly as well, but the validation issues persist. I'm sure the problem is in my xsd file somewhere, but I have no idea what that issue is. Any thoughts on my problem would be greatly appreciated.
EDIT:
When adding elementFormDefault= "qualified"
to my schema, the validation errors change, to: The 'testType' attribute is not declared.
, and the accompanying error: The required attribute 'http://test.org/test.xsd:testType' is missing.
Upvotes: 0
Views: 365
Reputation: 554
I think this is indeed due to namespace qualification, I do not know LINQ but it seems that the error:
The element 'testRoot' in namespace 'http://test.org/test.xsd' has nvalid
child element 'testObject' in namespace 'http://test.org/test.xsd'. List
of possible elements expected: 'testObject'
means the validator expects 'testObject' to be in no namespace while it received it in the 'http://test.org/test.xsd' namespace.
ElementFormDefault is by default unqualified
, so that means the root of your schema needs the namespace qualification but that the sub-elements do not need it.
Considering both elementFormDefault
and attributeFormDefault
not set or set to unqualified
, a valid XML instance of the schema above would be:
<tns:testRoot xmlns:tns="http://test.org/test.xsd">
<testObject testType="2">
<foo />
<bar />
</testObject>
</tns:testRoot>
So you should not add namespace to each element but only to the root one.
Let me know if I am not correct.
Upvotes: 1