How to Save a Generated XSD File - c#

I have some code (in c#) that creates a bunch of XML sheets on the fly. At the end of my code I am generating XSDs based on those XML sheets. I am making the XSDs successfully, but saving them as files is what I cannot figure out. My code so far is basically taken from the MSDN page on generating XSDs from XML sheets:
Directory.CreateDirectory(directoryName);
string[] directoryFiles = Directory.GetFiles(xmlFilePath);
foreach (string xFile in directoryFiles)
{
XmlReader reader = XmlReader.Create(xFile);
XmlSchemaSet schemaSet = new XmlSchemaSet();
XmlSchemaInference schema = new XmlSchemaInference();
schema.TypeInference = XmlSchemaInference.InferenceOption.Relaxed;
schemaSet = schema.InferSchema(reader);
//insert code here to save the file
//stored in schemaSet.Schemas()
}
Any help is appreciated. Thanks.

XMLSchemaSet has a method called Schemas() that returns a collection of all the schemas in the set. MSDN has a page that describes how to access these.
Simply access each Schema in the set using the code in the link above and write it using the example here.

Related

XDocument.Parse: Avoid replacing XXE references

I'm trying to protect against malicious XXE injections in the XMLs processed by my app. Therefore I'm using XDocument instead of XmlDocument.
The XML represents the payload of a web request so I call XDocument.Parse on its string content. However, I'm seeing the XXE references contained in the XML (&XXE) being replaced in the result with the actual value of ENTITY xxe.
Is it possible to parse the XML with XDocument without replacing &xxe ?
Thanks
EDIT:
I managed to avoid the replacement of xxes in the XML using XmlResolver=null for XDocument.Load
Instead of Parse try to use Load with a pre-configured reader:
var xdoc = XDocument.Load(new XmlTextReader(
new StringReader(xmlContent)) { EntityHandling = EntityHandling.ExpandCharEntities });
From MSDN:
When EntityHandling is set to ExpandCharEntities, the reader expands character entities and returns general entities as EntityReference nodes.
Use the following example to stop resolving XXE (schemas and DTD).
Dim objXmlReader As System.Xml.XmlTextReader = Nothing
objXmlReader = New System.Xml.XmlTextReader(_patternFilePath)
objXmlReader.XmlResolver = Nothing
patternDocument = XDocument.Load(objXmlReader)

C# DataSet validation from XML schema

I have a xml schema. I want to populate a DataSet and validate it using this schema.
DataSet package = new DataSet();
StringReader schemaResourceReader = new StringReader(PackageValidationLibrary.Properties.Resources.myPackage);
package.ReadXmlSchema(schemaResourceReader);
package.Tables["Table1"].Rows.Add(packageDetail.date,packageDetail.code,packageDetail.amount,packageDetail.place,"0");
package.Tables["Table2"].Rows.Add("0","0");
foreach (Cek data in recordList){
package.Tables["Table3"].Rows.Add(data.Serial, data.Code, data.Branch, data.ValidityDate, "0");
}
Using the code above I can load data but I cannot validate it although dataset imports the schema.
I tried to get xml string using package.GetXml() method and reload the xml again. Then I got exceptions.
How can I validate this table? Thanks.
EDIT
As I understand from answers and comments it is not possible to validate while populating the dataset. Then I read the xml from dataset and loaded it with the configuration given below.
_schema = XmlSchema.Read(new StringReader(PackageValidationLibrary.Properties.Resources.TakasPaketi), new ValidationEventHandler(ValidationEventHandler));
XmlReaderSettings _settings = new XmlReaderSettings();
_settings.Schemas.Add(_schema);
_settings.ValidationType = ValidationType.Schema;
XmlReader vreader = XmlReader.Create(stream, _settings);
I believe this will do it:
// First, read in the XML schema
DataSet MyDataSet = new DataSet();
MyDataSet.ReadXmlSchema(#"C:\YourSchema.xsd");
// Now, read in the XML file (it is validated
// against the schema when it is read in).
MyDataSet.ReadXml(#"C:\YourFile.xml");
If you edit the data xml file to not match the schema, an exception will be thrown when the xml file is read.
So in your case you may have to export the dataset to an xml string and then read it back in. You say you are getting exceptions when you do this....what exceptions? Maybe the data isn't valid for the schema you have.

Validate xml via dtd, different directory for dtd

I am trying to validate an xml file via a .dtd. I have write this validator:
public bool Validation(XmlDocument xmlDoc)
{
var xml = XmldocToString(xmlDoc);
var r = new XmlTextReader(new StringReader(xml));
var settings = new XmlReaderSettings();
var sb = new StringBuilder();
settings.ProhibitDtd = false;
settings.ValidationType = ValidationType.DTD;
settings.ValidationEventHandler += (a, e) =>
{
sb.AppendLine(e.Message);
_isValid = false;
};
XmlReader validator = XmlReader.Create(r, settings);
while (validator.Read())
{
}
validator.Close();
return _isValid;
}
The problem is that I must have the dtd file in bin directory of the Solution. I want to chose a diferent directory to keep the .dtd file and i really can't find how.
Thank you for your time.
Declare in the Xml file the association with the DTD:
Example in case the dtd is stored in a remote server:
<!DOCTYPE Catalog PUBLIC "abc/Catalog" "http://xyz.abc.org/dtds/catalog.dtd">
Take a look at that wiki page and at that site for more options and information about Xml files and DTD association.
Example in case the dtd is placed locally (SYSTEM):
How to reference a DTD from a document:
Assuming the top element of the document is spec and the dtd is placed
in the file mydtd in the subdirectory dtds of the directory from where
the document were loaded:
<!DOCTYPE spec SYSTEM "dtds/mydtd">
Notes:
The system string is actually an URI-Reference (as defined in RFC
2396) so you can use a full URL string indicating the location of your
DTD on the Web. This is a really good thing to do if you want others
to validate your document. It is also possible to associate a PUBLIC
identifier (a magic string) so that the DTD is looked up in catalogs
on the client side without having to locate it on the web. A DTD
contains a set of element and attribute declarations, but they don't
define what the root of the document should be. This is explicitly
told to the parser/validator as the first element of the DOCTYPE
declaration.
(Excerpt from here)

How to create the XDocument instance for loading the XML file after deserializing the the object?

I am developing window phone 7 application. I am new to the window phone 7 application. I am referring to the following link for XML Serialization & Deserialization.
http://www.codeproject.com/KB/windows-phone-7/wp7rssreader.aspx
In the above link the LoadFromIso() function is used for XML Deserialization. I want to load the xml file after deserialization in the above link. In simple one case we can do this as in the following code. Similar to the following code I want "doc" in the above link. In the following code we can perform the various opeations on the XML file by using LINQ to XML with following statement
doc = XDocument.Load(isfStream);
The complete code is as follows
IsolatedStorageFile isfData = IsolatedStorageFile.GetUserStoreForApplication();
XDocument doc = null;
IsolatedStorageFileStream isfStream = null;
if (isfData.FileExists(strXMLFile))
{
isfStream = new IsolatedStorageFileStream(strXMLFile, FileMode.Open, isfData);
doc = XDocument.Load(isfStream);
isfStream.Close();
}
In the similar way I want the instance of the XDocument after deserializing the object so that I can perform the various operations on the XML file by using LINQ to XML. Can you please provide me any code or link through which I can obtain the instance of the XDocument so that I can load the XML file & perform the various operation on the XML file by using the LINQ to XML ?
The variable doc in your code is an XDocument of the deserialized content.
You can perform your operations on/with doc.
A simple WP7 project demonstrating loading XML using XDocument and LINQ and data binding to a listbox here. As Matt advises the work gets done on your XDocument instance.
binding a Linq datasource to a listbox

Cannot validate against multiple xsd schemas in C#

I wanna verify a digitally signed xml against its schema definition while this schema actually contains this tag
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd" id="schema"/>
Then I tried to load schemas:
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(null, "a.xsd");
settings.Schemas.Compile();
I will get the following error
The 'http://www.w3.org/2000/09/xmldsig#:Signature' element is not declared.
You need to also load in the imported schema with another
settings.Schemas.Add([importednamespace], [pathtoimportedXSD]);
The scheme xmldsig-core-schema.xsd does not charge for security reasons since it makes reference to a DTD to validate the upload directory and add it as another scheme.
<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
this works
The solution is C#
XElement xsdMarkup = XElement.Load("C:\\Proyectos\\WindowService\\Sbif\\Schema\\Schema\\IndicadoresFinancieros-v1.0.xsd");
XElement xsdMarkup2 = XElement.Load("http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd");
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, xsdMarkup.CreateReader());
schemas.Add(null, xsdMarkup2.CreateReader());
schemas.Compile();
are you sure hash is required at the end of?:
http://www.w3.org/2000/09/xmldsig#
From the error it would seem the XML Signature schema is not being loaded, despite the import.
Adding the XML Signature schema to the schema set explicitly should confirm that.
The most likely cause is the schema set's XmlReslver is not finding the file you specify, this could be a current folder/relative path issue.
Using Process Monitor to see where you could is trying to load the XSD file may also help.

Categories

Resources