XSD question

  • Thread starter Thread starter Mike P
  • Start date Start date
M

Mike P

In an XSD, I want to check for my XML having at least one <folder> tag
within a <folders> tag e.g.

<?xml version="1.0" encoding="utf-8" ?>
<folders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<folder>
<source>\\lpt0224\c$\testfolder</source>
<destination>\\slnapp02\c$\testfolder</destination>
<frequency>daily</frequency>
<backupbeforedelete>5</backupbeforedelete>
<backedup>0</backedup>
<lastbackup>23/10/2008</lastbackup>
</folder>
<folder>
<source>\\lpt0224\c$\testfolder2</source>
<destination>\\slnapp02\c$\testfolder2</destination>
<frequency>weekly</frequency>
<backupbeforedelete>2</backupbeforedelete>
<backedup>1</backedup>
<lastbackup>22/10/2008</lastbackup>
</folder>
</folders>

What is wrong with my XSD below?

<?xml version="1.0" encoding="iso-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="folders">
<xs:complexType>
<xs:sequence>
<xs:element name="folder" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="source" type="xs:string"
minOccurs="1" />
<xs:element name="destination"
type="xs:string" minOccurs="1" />
<xs:element name="frequency"
type="Frequency" minOccurs="1" />
<xs:element name="backupbeforedelete"
type="xs:integer"
minOccurs="1" />
<xs:element name="backedup"
type="xs:integer" minOccurs="1" />
<xs:element name="lastbackup"
type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="Frequency">
<xs:restriction base="xs:string">
<xs:enumeration value="daily" />
<xs:enumeration value="weekly" />
<xs:enumeration value="monthly" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
 
Mike said:
In an XSD, I want to check for my XML having at least one <folder> tag
within a <folders> tag e.g.

<?xml version="1.0" encoding="utf-8" ?>
<folders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<folder>
<source>\\lpt0224\c$\testfolder</source>
<destination>\\slnapp02\c$\testfolder</destination>
<frequency>daily</frequency>
<backupbeforedelete>5</backupbeforedelete>
<backedup>0</backedup>
<lastbackup>23/10/2008</lastbackup>
</folder>
<folder>
<source>\\lpt0224\c$\testfolder2</source>
<destination>\\slnapp02\c$\testfolder2</destination>
<frequency>weekly</frequency>
<backupbeforedelete>2</backupbeforedelete>
<backedup>1</backedup>
<lastbackup>22/10/2008</lastbackup>
</folder>
</folders>

What is wrong with my XSD below?

<?xml version="1.0" encoding="iso-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="folders">
<xs:complexType>
<xs:sequence>
<xs:element name="folder" minOccurs="1">

You need maxOccurs="unbounded" for the folder element, or at least
maxOccurs="2" to match the input sample you posted.
 
When I try to validate the XML against the schema I get the following
error :

'Data at the root level is invalid. Line 1, position 1'


Any ideas why?
 
Mike said:
When I try to validate the XML against the schema I get the following
error :

'Data at the root level is invalid. Line 1, position 1'


Any ideas why?

How exactly do you try to validate the XML? Are you using .NET code do
to that? Which one exactly?
 
I am putting the XSD file on a web server, referencing it in the XML
file, and then using the following code :

xmlDoc = new XmlDocument();

xmlDoc.Load(@"c:\copyfolder\copydetails.xml");

//validate xml against xsd
XmlTextReader tr = new XmlTextReader(new
StringReader(xmlDoc.ToString()));
XmlValidatingReader trv = new XmlValidatingReader(tr);

trv.ValidationType = ValidationType.Schema;

while (trv.Read())
{
}

public void ValidateAgainstSchema(object sender, ValidationEventArgs
args)
{
blnInvalidXML = true;
}
 
Mike said:
I am putting the XSD file on a web server, referencing it in the XML
file, and then using the following code :

xmlDoc = new XmlDocument();

xmlDoc.Load(@"c:\copyfolder\copydetails.xml");

//validate xml against xsd
XmlTextReader tr = new XmlTextReader(new
StringReader(xmlDoc.ToString()));

That is completely wrong and can't work as the ToString() call on an
XmlDocument instance does not give you the document's XML markup. You
would need xmlDoc.OuterXml for that.

But the whole approach is wrong:
If you use .NET 2.0 and later then you should and could simply use an
XmlReader created with the proper XmlReaderSettings for validation. If
you also want to have an XmlDocument then pass that XmlReader to the
Load method.

If you really want to validate after creating your XmlDocument then
there is a Validate method
http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.validate.aspx
 
Mike said:
Do you have a code example of this?

XmlReaderSettings xrs = new XmlReaderSettings();
xrs.ValidationType = ValidationType.Schema;
xrs.ValidationFlags |=
XmlSchemaValidationFlags.ReportValidationWarnings;
xrs.Schemas.Add(null, "schema1.xsd");
// add further schemas if needed
xrs.ValidationEventHandler += delegate(object sender,
ValidationEventArgs vargs)
{
Console.WriteLine("{0}: {1}", vargs.Severity,
vargs.Message);
};

XmlDocument doc = new XmlDocument();
using (XmlReader rd = XmlReader.Create("file.xml", xrs))
{
doc.Load(rd);
}
 
When specifying the schema in the code example, does this mean I no
longer need to reference the schema in my XML file in
xsi:noNamespaceSchemaLocation?
 
Mike said:
When specifying the schema in the code example, does this mean I no
longer need to reference the schema in my XML file in
xsi:noNamespaceSchemaLocation?

No, you don't need that, you can simply call
xrs.Schemas.Add(null, "schema1.xsd");
to add schemas as needed the XmlSchemaSet the XmlReader created from
your XmlReaderSettings xrs is going to use.
 
Back
Top