I have a problem when I select node elements from an xml file and validata
each node againts the schema. I use XmlValidatingReader and it complains
about elements not being declared.
I have defined a schema for details of a particular service request. Below
is a schema similar to the one that I defined:
<?xml version="1.0" standalone="yes" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.mycompany.com"
xmlns="http://www.mycompany.com" xmlns:dsc="http://www.mycompany.com"
xmlns:msprop="urn:schemas-microsoft-com:xml-msprop"
elementFormDefault="qualified">
<xs:element name="Requests">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="Input1" type="xs:unsignedLong" minOccurs="1"
maxOccurs="1" />
<xs:element name="Input2" type="xs:unsignedLong" minOccurs="1"
maxOccurs="1" />
<xs:element name="Response" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Result" type="xs:boolean" />
<xs:element name="Message" type="xs:string" />
<xs:element name="DateTime" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
A simple Xml file that conforms to the above schema would have batched
requests and look like
<?xml version="1.0"?>
<tst:Requests xmlns:tst="http://www.mycompany.com">
<tst:Request>
<tst:Input1>1</tst:Input1>
<tst:Input2>2</tst:Input2>
</tst:Request>
<tst:Request>
<tst:Input1>3</tst:Input1>
<tst:Input2>4</tst:Input2>
</tst:Request>
</tst:Requests>
I have a program that validates and processes this XML file. What I would
like to do is that if the xml file is valid but some of the request elements
do not conform to my schema, I would still process the ones that are valid
(against my schema). So what I do is:
1) Load the Xml file and select the request nodes. This step would make sure
that the xml file is well formed (valid). Below is the snippet and it works
fine.
XmlTextReader rdr = new XmlTextReader(xmlFile);
System.Xml.XmlDocument doc = new XmlDocument();
doc.Load(rdr);
//Create a namespace manager
System.Xml.XmlNamespaceManager nsMngr = new
XmlNamespaceManager(doc.NameTable);
nsMngr.AddNamespace("tst","http://www.mycompany.com");
//
System.Xml.XmlNodeList rqstLst =
doc.SelectNodes("tst:Requests/tst:Request",nsMngr);
//
foreach(XmlNode nd in rqstLst)
{
if( ValidateRequestXml(nd.OuterXml))
{
ProcessRequest(nd.OuterXml);
}
}
2) In ValidateRequestXml, I try to validate just the part of the Xml file
(request element). If it is ok, I can process it. Otherwise, I go to the
next request. This way, a request that does not conform to my schema will
not prevent the processing of valid requests. This is what I do:
NameTable nt = new NameTable();
XmlNamespaceManager nsMngr = new XmlNamespaceManager(nt);
nsMngr.AddNamespace("txt","http://www.mycompany.com");
System.Xml.XmlParserContext rqstCtx = new
XmlParserContext(null,nsMngr,null,XmlSpace.None);
XmlValidatingReader vRdr = new
XmlValidatingReader(xmlRequest,XmlNodeType.Element ,rqstCtx); //xmlRequest is
nd.OuterXml from step 1
vRdr.Schemas.Add("http://www.mycompany.com",xmlSchema);
vRdr.ValidationEventHandler +=new
ValidationEventHandler(vRdr_ValidationEventHandler );
Requests ds = new Requests(); //Dataset generated from the schema. I
just read each request into it
ds.ReadXml(vRdr);
xmlRequest is the OuterXml of the selected node elements passed to
ValidateRequestXml and includes a namespace definition. For examples, it
would look like:
<tst:Request xmlns:tst="http://www.mycompany.com">
<tst:Input1>1</tst:Input1>
<tst:Input2>2</tst:Input2>
</tst:Request>
However, the validating reader seems to have a problem with the inclusion of
the definition of the namespace in the node element. It raises validation
events when I call ds.ReadXml(vRdr) saying that
'http://www.mycompany.com:Request" element not is not declared.
'http://www.mycompany.com:Input1" element not is not declared.
'http://www.mycompany.com:Input2" element not is not declared.
Is the definition of namespace in the selected node causing the validation
to look for the declaration of the elements in a subnamespace?
If I remove the namespace definition from the selected node, the validation
seems to be working ok. Could someone give me an explaination and possibly a
solution or an alternative way of doing partial (element-only) schema
validations?
Your responses and time are deeply appreciated.
Matt