all groups > dotnet xml > april 2007 >
You're in the

dotnet xml

group:

Accessing an XSD file


Accessing an XSD file Doug
4/18/2007 5:22:34 AM
dotnet xml:
I'm trying to access a schema file as such:

Dim settings As XmlReaderSettings = New
XmlReaderSettings()
settings.Schemas.Add(webServiceNamespace, schemaFileName)
settings.ValidationType = ValidationType.Schema

Even though the webServiceNamespace value above is set to an intranet
address, I keep getting this error:

Could not find file 'C:\Program Files\Microsoft Visual Studio
8\Common7\IDE\XmlCommand.xsd

Why is it looking for the XSD file there? Is there a way to have it
look in the actual spot I put in my code?
Re: Accessing an XSD file Doug
4/18/2007 7:17:40 AM
That worked. But now I'm having a problem with the validate method
that I'm trying to use to validate my xml against my schema. Below is
my code and when it does the xmlDoc.Validate method I get the error:
"The XmlSchemaSet on the document is either null or has no schemas in
it. Provide schema information before calling Validate." Do you know
what might be causing that?

Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add(Nothing, schemaFilePath)
settings.ValidationType = ValidationType.Schema

Dim xmlDoc As XmlDocument = New XmlDocument()
xmlDoc.LoadXml(xmlCommandString)

Dim eventHandler As ValidationEventHandler = New
ValidationEventHandler(AddressOf ValidationEventHandler)
xmlDoc.Validate(eventHandler)
Re: Accessing an XSD file Doug
4/18/2007 8:52:32 AM
That did the trick. Thank you!
Re: Accessing an XSD file Doug
4/18/2007 9:47:31 AM
I guess I kind of lied. The code steps through just fine, but the
validation doesn't work. I tried to put some bad xml through this and
it did not do anything to indicate the xml was bad. Here is my final
code if anyone has any idea why it isn't working (I did verify that
the server.mappath function gets me the right result to where my XSD
file is)

Private Function LoadXml(ByVal xmlCommandString As String) As
XmlDocument
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add(Nothing, Server.MapPath(schemaFileName))
settings.ValidationType = ValidationType.Schema

Dim stringRdr As New StringReader(xmlCommandString)
Dim xmlRdr As XmlReader
xmlRdr = XmlReader.Create(stringRdr, settings)

Dim xmlDoc As XmlDocument = New XmlDocument()
xmlDoc.Load(xmlRdr)

Dim eventHandler As ValidationEventHandler = New
ValidationEventHandler(AddressOf ValidationEventHandler)
xmlDoc.Validate(eventHandler)

Return xmlDoc
End Function

Private Shared Sub ValidationEventHandler(ByVal sender As Object,
ByVal args As ValidationEventArgs)
Throw New XmlSchemaException(schemaFileValidationErrorMessage &
args.Message)
End Sub

Re: Accessing an XSD file Doug
4/18/2007 11:34:20 AM
This is only a portion of the schema, I haven't tested it with just
this, I tested it with the full version:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XmlCommand" elementFormDefault="qualified"
version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://intranet/hstServices/Schemas/XmlCommand.xsd"
xmlns="http://intranet/hstServices/Schemas/XmlCommand.xsd"
xmlns:NS="http://intranet/hstServices/Schemas/XmlCommand.xsd">
<xs:attribute name="name" type="xs:string" />
<xs:element name="XmlCommand">
<xs:complexType>
<xs:sequence>
<xs:element name="Email" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:element name="Success">
<xs:complexType>
<xs:sequence>
</xs:sequence>
<xs:attribute name="address" use="optional"
type="xs:string" />
<xs:attribute name="subject" use="optional"
type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="connectionKey" use="required"
type="xs:string" />
</xs:complexType>
</xs:element>
</xs:schema>

And here is my xml. I have tried removing the connectionKey value
from the beginning of the xml and it still validates just fine.

<XmlCommand connectionKey='dbStarrs'>
<Email>
<Success address='DWhite@ABC.com' subject='SuccessTest'/>
</Email>
</XmlCommand>
Re: Accessing an XSD file Martin Honnen
4/18/2007 3:06:12 PM
[quoted text, click to view]

The second argument to the Add method is the location. The first
argument is simply the namespace URI which is not a location. So pass in
the location as the second argument. For the first argument you can pass
in Nothing, that way the XML parser uses the namespace defined in the
schema.



--

Martin Honnen --- MVP XML
Re: Accessing an XSD file Martin Honnen
4/18/2007 4:33:05 PM
[quoted text, click to view]

You need to use the above settings when loading the XML e.g. instead of
LoadXml use
xmlDoc.Load(XmlReader.Create(New StringReader(xmlCommandString),
settings))

Or as an alternative way, if you only want to validate after loading the
XML, you need to create an XmlSchemaSet and set xmlDoc.Schemas to that
XmlSchemaSet, after you have added your schema(s) to the schema set.

--

Martin Honnen --- MVP XML
Re: Accessing an XSD file Martin Honnen
4/18/2007 7:21:35 PM
[quoted text, click to view]

Please post a minimal schema and XML that you are testing, then we can
say more.


--

Martin Honnen --- MVP XML
Re: Accessing an XSD file Martin Honnen
4/19/2007 12:00:00 AM
[quoted text, click to view]

So this schema defines an XmlCommand element in its targetNamespace
which is http://intranet/hstServices/Schemas/XmlCommand.xsd.

Your XML sample however has

[quoted text, click to view]

an XmlCommand element in no namespace. What happens in this case is the
the XML parser looks at the root element, finds it is in no namespace
and then looks for a schema for no namespace. It does not have one
however and that way it simply does lax validation only.

If you set up an XmlReader with a ValidationEventHandler to report
warnings then you will get a warning that the parser does not find a
schema. However the design of the Validate method you are using is a bit
flawed as it does not allow you to get warnings, it only reports errors.

See also
<http://blogs.msdn.com/xmlteam/archive/2007/04/02/to-trust-or-not-to-trust.aspx>
which recommends "DO TURN ON the ReportValidationWarnings flag".


--

Martin Honnen --- MVP XML
Re: Accessing an XSD file Doug
4/19/2007 5:29:44 AM
Hi Martin, so if I understood you correctly part of the issue is that
my sample did not have a targetNamespace within (I think that is what
that blog was talking about too). But, I added this line of code into
my application and it did not even report the warning that the blog
talked about.

settings.ValidationFlags =
XmlSchemaValidationFlags.ReportValidationWarnings

Is there another way to do this validation then the way I'm doing it?
Re: Accessing an XSD file Doug
4/19/2007 5:47:08 AM
If I add the targetNamespace in, and then send in bad xml, it will
throw an error before it gets to the xmlDoc.Validate command (it does
it when it tries to Load the XML).

In essence, this is fine, because the error is what I am expecting,
but because it's not doing it in the location that I expect, I'm not
trapping it in the way I'd like. (Plus, I'd really like to figure out
why the .Validate won't work!) :)
Re: Accessing an XSD file Doug
4/19/2007 7:38:22 AM
That did do the trick this time. Thank you very much for your help!

Re: Accessing an XSD file Martin Honnen
4/19/2007 3:19:31 PM
[quoted text, click to view]

As I tried to point out in my previous response, it is unfortunately not
possible to report warnings with the Validate method.

[quoted text, click to view]

Yes, the Validate method is mostly meant to Validate an XmlDocument that
has been manipulated with e.g. CreateElement/AppendChild.

If you simply want to validate your XML string you can do it directly
when parsing it e.g. (pseudo code)

Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add(Nothing, schemaFilePath)
settings.ValidationType = ValidationType.Schema
settings.ValidationFlags = settings.ValidationFlags And
XmlSchemaValidationFlags.ReportValidationWarnings
AddHandler settings.ValidationEventHandler, New
ValidationEventHandler(AddressOf ValidationEventHandler)

Using Reader As XmlReader = XmlReader.Create(New
StringReader(xmlCommandString), settings)
Dim xmlDoc As XmlDocument = New XmlDocument()
xmlDoc.Load(Reader)

That way the XmlReader will do the validation and report warnings and
errors to the ValidationEventHandler.

You do not need an XmlDocument at all to do the validation, the
XmlReader would suffice plus a simple loop that reads through the XML
document but your earlier code snippets looked as if you use the
XmlDocument elsewhere so I have left that in.


--

Martin Honnen --- MVP XML
AddThis Social Bookmark Button