Why my xml file is detected as a valid xml? - c#

I wanted to find a xsd file for MS office Docx's [Content_Types].xml file (Where can I find the XSDs of DOCX XML files?)
I got an answer, but I've found that for some reason this xsd cause all of my xml files to pass validation test
This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<Export_toLab Sending_Site="3">
<Tracker Tracker_ID="55" Booklet_Type="3">
<Booklet Booklet_ID="542"/>
</Tracker>
</Export_toLab>
This is the xsd file (schema of MS office Docx's [Content_Types].xml):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="http://schemas.openxmlformats.org/package/2006/content-types"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.openxmlformats.org/package/2006/content-types"
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
<xs:element name="Types" type="CT_Types"/>
<xs:element name="Default" type="CT_Default"/>
<xs:element name="Override" type="CT_Override"/>
<xs:complexType name="CT_Types">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Default"/>
<xs:element ref="Override"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="CT_Default">
<xs:attribute name="Extension" type="ST_Extension" use="required"/>
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
</xs:complexType>
<xs:complexType name="CT_Override">
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
<xs:attribute name="PartName" type="xs:anyURI" use="required"/>
</xs:complexType>
<xs:simpleType name="ST_ContentType">
<xs:restriction base="xs:string">
<xs:pattern
value="(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>#,;:\\"/\[\]\?=\{\}\s\t]])+))/((([\p{IsBasicLatin}-[\p{Cc}\(\)<>#,;:\\"/\[\]\?=\{\}\s\t]])+))((\s+)*;(\s+)*(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>#,;:\\"/\[\]\?=\{\}\s\t]])+))=((([\p{IsBasicLatin}-[\p{Cc}\(\)<>#,;:\\"/\[\]\?=\{\}\s\t]])+)|("(([\p{IsLatin-1Supplement}\p{IsBasicLatin}-[\p{Cc}"\n\r]]|(\s+))|(\\[\p{IsBasicLatin}]))*"))))*)"
/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ST_Extension">
<xs:restriction base="xs:string">
<xs:pattern
value="([!$&'\(\)\*\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:#]|[a-zA-Z0-9\-_~])+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
This is the validation code:
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("http://schemas.openxmlformats.org/package/2006/content-types", "opc-contentTypes.xsd");
XDocument doc = XDocument.Load("MyFile.xml");
string msg = "";
doc.Validate(schemas, (o, e) => {msg += e.Message + Environment.NewLine;});
Console.WriteLine(msg == "" ? "Document is valid" : "Document invalid: " + msg);
Why the xml file is deteced as a valid xml?
Thanks

I think you may have the same issue as here:
XDocument.Validate is always successful
To summarise, the validate method does not raise an error for the nodes it does not know about. You should simply check before validating that the namespace of the xml is the same as the schema - if not its definitely a fail so no need to validate.

Related

How to iterate/traverse XML file elements( which contains different namespaces) to convert it as Data table in C#

I have a sample to read a xml schema set for a xml file which contains different namespaces. For this i can get different schema for each namespace as i explained below.
Sample File:
<?xml version="1.0" encoding="utf-8"?>
<data xmlns:d="http://sampleschema/dataservices" xmlns:m="http://sampleschema/dataservices/metadata">
<content>
<m:properties>
<d:CustomerID>ALFKI</d:CustomerID>
<d:CompanyName>Alfreds Futterkiste</d:CompanyName>
</m:properties>
</content>
</data>
Sample Code to get XML Schema Set:
strFileName = #"C:\Sample\Sample.xml";
XmlReader reader = XmlReader.Create(strFileName);
XmlSchemaInference schema = new XmlSchemaInference();
XmlSchemaSet schemaSet = schema.InferSchema(reader);
It gives three different types of schemas while using the above code. But my requirement will be i need a single schema for the entire xml file which contain any number of namespaces in it. I have checked with possibilities of codes in msdn and stack overflow. I can't find any proper solution for this.
The expected schema output will be like below.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="m:properties">
<xs:complexType>
<xs:sequence>
<xs:element name="d:CustomerID" type="xs:string"></xs:element>
<xs:element name="d:CompanyName" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="xmlns:d" type="xs:string"></xs:attribute>
<xs:attribute name="xmlns:m" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Any one can help to achieve this requirement.
Thanks in advance.
Try something like this :
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:m="http://www.w3.org/2001/XMLSchema" xmlns:d="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="content">
<m:complexType>
<m:sequence>
<m:element name="properties">
<d:complexType>
<d:sequence>
<d:element name="CustomerID" type="xs:string"></d:element>
<d:element name="CompanyName" type="xs:string"></d:element>
</d:sequence>
</d:complexType>
</m:element>
</m:sequence>
</m:complexType>
</xs:element>
</xs:sequence>
<d:attribute name="xmlns_d" type="d:string"></d:attribute>
<m:attribute name="xmlns_m" type="d:string"></m:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

Why does this XML validate, when it shouldn't?

I have the following XSD files:
ReadFile.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="elsag:lprcore" elementFormDefault="qualified" targetNamespace="elsag:lprcore" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="Read.xsd" />
<xs:element name="reads" type="ReadFile" />
<xs:complexType name="ReadFile">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="read" nillable="true" type="read">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Read.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="elsag:lprcore" elementFormDefault="qualified" targetNamespace="elsag:lprcore" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="Snapshot.xsd"/>
<xs:include schemaLocation="GPS.xsd"/>
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:element name="read" type="read"/>
<xs:complexType name="read">
<xs:complexContent mixed="false">
<xs:extension base="snapshot">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="timestamp" type="xs:dateTime" />
<xs:element minOccurs="1" maxOccurs="1" name="plate" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="state" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="confidence" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1" name="overviews">
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="snapshot" type="snapshot"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="1" name="gps" type="gps" />
</xs:sequence>
<xs:attribute name="id" type="guid" use="required" />
<xs:attribute name="camera" type="xs:string" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Please note that there are more files that make up the XSD, but I don't believe they're relevant to the problem so I did not include them.
I'm using the following code to validate XML files being processed. I want to reject any file that doesn't validate without errors:
StringBuilder validationErrors = new StringBuilder();
inDoc.Validate( schemas, ( o, e ) => {
validationErrors.AppendLine( e.Message );
} );
if ( !string.IsNullOrWhiteSpace( validationErrors.ToString() ) ) {
. . .
}
I've passed the following XML file to the code above and the code does not generate any validation error messages for it.
<read>
<timestamp>2015-07-17T16:20:18.1540000-04:00</timestamp>
<plate>FED456</plate>
</read>
I would have thought that the lack of the reads tag surrounding the read tag would have caused the XML to fail validation. Is the problem in the validation code or is it in the XSD or is this normal?
EDIT:
Here is the code that initializes the schemas variable:
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add( "elsag:lprcore", #"XML\ReadFile.xsd" );
Because you have defined
<xs:element name="read" type="read"/>
the read element is a valid root element for your XML. Every element which is an immediate child of <xs:schema> is eligible for being a root element (even those in an included schema).
Thanks to information posted in the answer by Glorfindel and the link posted by overslacked, I've been able to get the XML validation in my program to work.
The problem was that the program would not flag an XML file that does not contain a namespace as invalid. The cause is that the XDocument.Validate extension method creates an XmlReader object whose XmlReaderSettings property does not contain the ReportValidationWarnings flag. As a result, the ValidationEventHandler delegate passed to the method is not called for these files.
To make the validation logic work, I defined a new extension method that includes the flag:
internal static class XmlValidationExtension {
public static void ValidateWithWarnings( this XDocument doc, XmlSchemaSet schemas, ValidationEventHandler validationCallback ) {
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add( schemas );
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler( validationCallback );
XmlReader reader = XmlReader.Create( doc.CreateReader(), settings );
while ( reader.Read() ) ;
}
}
This is essentially the same exact code from the question linked to by overslacked, but where the XmlReader is created by calling the XDocment object's CreateReader method.
This code now considers any XML file which does not use the correct namespace to be invalid. Any other part of the XML that does not match the XSD is also flagged.

SQLite create DB table from xml (xsd)

I have xml (xsd) file. I need create db table in SQLite db, and load data from XML to this table (in C# application).
I try to use this code:
string ConnectionStr = "Data Source=mydb.sqlite;Version=3; New=True; Compress = True;";
NDbUnit.Core.INDbUnitTest Database = new NDbUnit.Core.SqlLite.SqlLiteDbUnitTest(ConnectionStr);
Database.ReadXmlSchema("AS_ACTSTAT.xsd");
Database.ReadXml("AS_ACTSTAT.xml");
Database.PerformDbOperation(NDbUnit.Core.DbOperationFlag.CleanInsertIdentity);
But I have this error (read xml schema):
SqlDbCommandBuilder.CreateSelectCommand(DataSet, string) failed for
tableName = 'ActualStatus'
Schema file:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:usch="http://www.unisoftware.ru/schematron-extensions" xmlns:sql="urn:schemas-microsoft-com:mapping-schema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="ActualStatuses" sql:is-constant="true" >
<xs:annotation>
<xs:documentation>sostav</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="ActualStatus" maxOccurs="unbounded" sql:relation="AS_ACTSTAT">
<xs:annotation>
<xs:documentation>status</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="ACTSTATID" use="required">
<xs:annotation>
<xs:documentation>key</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="NAME" use="required">
<xs:annotation>
<xs:documentation>name
0 – non actual
1 – actual
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
ps Also I try use SqlXml 4.0 from Microsoft (it works great with MS SQL 2008), but can't find OLEDB driver for SQLite.
Any idea? I need something like SqlXml 4.0 fo SQlite, because i dont know structure of xml file previously.

Can't get xs:element with attribute

I have XML elements with and without attributes
<xs:element name='element0'>
<xs:complexType name='internationalShoeSize'>
<xs:annotation>
<xs:documentation>Data ...</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='attribute0' type='xs:string' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name='element1'>
<xs:complexType name='internationalShoeSize'>
<xs:annotation>
<xs:documentation>Data1 ...</xs:documentation>
</xs:annotation>
</xs:element>
When I get the elements in a DataTable, only get the elements without attributes.
foreach(DataColum colum in table.colums)
{
....
}
This foreach only get the elements without attributes: the element1.
How can I get all the elements, with and without attributes?
I think you need to start with a better schema snippet, the one you've posted is mangled beyond use. I took yours and cleaned it up - in the process maybe deviated from your intentions; feel free to take my sample and used it to edit your question for better illustration.
(Alternatively, if you have a sample XML, post that instead - it might be even easier to explain.)
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="element0" type="internationalShoeSize"/>
<xs:element name="element1" type="internationalShoeSize"/>
<xs:complexType name="internationalShoeSize">
<xs:annotation>
<xs:documentation>Data ...</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="attribute0" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
Meanwhile, this is the equivalent data structure you would get (on .NET):
Your attribute is there...

Deserialize a XML fragment to class that has been generated by xsd.exe

I have a xml file that I want to read it and then interpret and convert to respective classes that were generated from xsd tool. Here are the steps which I am trying:
I created a XSD file.
Converted the respective xsd file into respective set of classes.
I made some xml files through same set of classes (from step 2) and xmlserializer.
Now I am reading back from those xml files and I wan't to convert it into classes (generated from step2)
I am pasting the code I have worked till now, I seem to get an exception when I am deserializing, {"There is an error in XML document (0, 0)."}
var doc = XDocument.Load(filePath);
var query2 = from b in doc.Root.Descendants()
select b;
foreach (var item in query2)
{
switch (item.Name.LocalName)
{
case "SomeStringValue":
XmlSerializer srz = new XmlSerializer(typeof(SomeClassGeneratedfromXSD));
var writer=item.CreateReader();
parameterFromFile.SomeProperty = (SomeClassGeneratedfromXSD)srz.Deserialize(writer);
//srz.Deserialize(item);
break;
I am pasting a snippet of what my xsd looked like:
<xs:complexType name="Parameters">
<xs:all>
<xs:element name="A">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="mstns:Restricted8CharString">
<xs:attribute name="Caption" use="required" fixed="Caption for A">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="ActionWhenMaxReached" use="required">
<xs:simpleType>
<xs:restriction base="xs:short">
<xs:pattern value="[1-3]"></xs:pattern>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Expression" type="xs:string" default="0" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="B">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:short">
<xs:attribute name="Caption" use="prohibited">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="ActionWhenMaxReached" use="required">
<xs:simpleType>
<xs:restriction base="xs:short">
<xs:pattern value="[1-3]"></xs:pattern>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Expression" type="xs:string" default="0" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
Your closing tag is incorrect. It should be:
</xs:complexType>
and not
</xs:complexType name="Parameters">
After struggling, I have found out the solution:
Actually I was trying to parse an inner element, which was incorrect; I was already having the classes from the xsd tool, so I can Simply use the code as:
XmlSerializer serializer = new XmlSerializer(typeof(RootClass));
using (TextReader reader = new StreamReader(filePath))
{
RootClass parameterFromFile = (RootClass)serializer.Deserialize(reader);
}

Categories