问题
I'm running into real difficulties validating XML with XSD. I should prefix all of this and state up front, I'm new to XSD and validation, so I'm not sure if it's a code issue or an XML issue. I've been to XML API hell and back with the bajillion different options and think that I've found what would be the ideal strategy for validating XML with XSD. Note, my XML and XSD are coming from a database, so I don't need to read anything from disk.
I've narrowed my problem down into a simple sample Windows Forms application. It has a textbox for XSD (txtXsd), a textbox for XML (txtXml), a textbox for the result (txtResult), and a button to start the validation (btnValidate).
I'm using a sample XSD file from Microsoft,
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:bookstore-schema" elementFormDefault="qualified" targetNamespace="urn:bookstore-schema">
<xsd:element name="title" type="xsd:string" />
<xsd:element name="comment" type="xsd:string" />
<xsd:element name="author" type="authorName"/>
<xsd:complexType name="authorName">
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string" />
<xsd:element name="last-name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
I'm using the following code in my application.
private void btnValidate_Click (object sender, EventArgs e)
{
try
{
XmlTextReader reader = new XmlTextReader(txtXsd.Text, XmlNodeType.Document, new XmlParserContext(null, null, String.Empty, XmlSpace.None));
XmlSchema schema = XmlSchema.Read(reader, null);
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(schema);
XDocument doc = XDocument.Parse(txtXml.Text);
doc.Validate(schemas, ValidateSchema);
}
catch (Exception exception)
{
txtResult.Text += exception.Message + Environment.NewLine;
}
}
private void ValidateSchema (Object sender, ValidationEventArgs e)
{
txtResult.Text += e.Message + Environment.NewLine;
}
As a test, I put in valid XML, but what I think should not conform to the XSD above.
<xml>
<bogusNode>blah</bogusNode>
</xml>
The result is nothing, no validation errors whatsoever. How do I fix it?
回答1:
Well, for one - your XSD defines a XML namespace xmlns="urn:bookstore-schema"
which is not present in your XML test file - therefore, nothing in your XML test file will be validated.
If you remove those elements form your schema:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="title" type="xsd:string" />
then it will properly validate your XML test file and complain about the wrong elements.
Also using an element named <xml>
might not be a great idea - since the directive <?xml ......?>
is a pre-defined directive and should not appear as tag name elsewhere in your document.
Marc
回答2:
I don't want the user to submit XML that's not defined in the XSD.
Why do you care? Your schema validates the XML nodes that are in your namespace. Your processing logic processes the XML nodes that are in your namespace. Nodes that aren't in your namespace aren't relevant to either your schema or your logic.
If it's truly essential to restrict all nodes in the XML document to a specific namespace, you can accomplish that by extending the basic XmlReader
validating logic found here.
public static void Main()
{
const string myNamespaceURN = "urn:my-namespace";
XmlSchemaSet sc = new XmlSchemaSet();
sc.Add(myNamespaceURN, "mySchema.xsd");
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas = sc;
settings.ValidationEventHandler += ValidationCallBack;
XmlReader reader = XmlReader.Create("myDocument.xml", settings);
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element ||
reader.NodeType == XmlNodeType.Attribute)
&&
reader.NamespaceURI != myNamespaceURN)
{
LogError(reader.NamespaceURI + " is not a valid namespace.");
}
}
}
private static void ValidationCallBack(object sender, ValidationEventArgs e)
{
LogError(e.Message);
}
private static void LogError(string msg)
{
Console.WriteLine(msg);
}
回答3:
You may also try XmlValidatingReader for XML validation
来源:https://stackoverflow.com/questions/943131/validating-xml-with-xsd