Validate XDocument against a particular schema - c#

I have an XDocument file that I have loaded. (confirmed the working). I need to validate this document. To do so I have an XSD file that I attached to the project as a embedded resource. I load
the xsd with these line of code:
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream("Project.Models.Ci.def.xsd");
How can I now validate the XML against this XSD? I only need to know if the document is valid or not, so nothing fancy.

There is a Validate extension method that might meet your needs. Take a look at this documentation on MSDN - it has sample code as well:
Extensions.Validate Method (XDocument, XmlSchemaSet, ValidationEventHandler, Boolean)

Related

Loading XML file from UNC Path not working propertly

I want to load an XML file located on my server so I can get the value of the XML Element called "CheckInterval" and store it on a string called "NewIntervalSet".
I am loading the following XML file called "ConfigFile.xml".
<?xml version="1.0" encoding="utf-8"?>
<Cart>
<CartConfiguration>
<CheckInterval>0.25</CheckInterval>
</CartConfiguration>
</Cart>
The way that I am loading it is the following:
XElement xelement;
xelement = XElement.Load(Path.Combine("\\\\server\\public\\Engineering","ConfigFile.xml"));
The way that I'm storing the XML element "CheckInterval" into the string "NewIntervalSet" is the following:
string NewIntervalSet;
NewIntervalSet=xelement.Descendants("CartConfiguration")
.Select(x => x.Element("CheckInterval").Value).FirstOrDefault();
When I place a breakpoint where the file is being loaded I can see that the file is loading correctly, so I know the path is right, but when it tries to select the XML element it skips this line of code and it returns a null value, therefore a null string on the "NewIntervalSet" variable. I have no idea why is doing this, when I use the same code but the path is on the local machine it works correct.
Your program may be running into a permissions issue. According to MSDN, XElement creates by calling XmlReader.Create, which in turn has the following to say
A default XmlUrlResolver with no credentials is used to access any
external resources such as a document type definition (DTD), entities,
schemas, and so on. If the external resource is located on a network
resource that requires authentication, specify an XmlResolver with the
necessary credentials using the XmlReaderSettings.XmlResolver
property.
Since your XML document is located on a network path, it's using default/null credentials, causing it to get no read permissions and an empty document. Try opening the file as a stream so you can make a run where it reads out text, and then pipe that stream into a new XElement using this overload. Alternatively, instantiate the XmlResolver yourself so you can set the credentials.
I fix this problem by loading the XML file as an XDocument and not as an XElement. The new way that I'm loading the XML file is the following:
XDocument xDocument;
xDocument= XDocument.Load(Path.Combine("\\\\server\\public\\Engineering","ConfigFile.xml"));

ReadXml from a Resource - Explanation

I've been working on a project (C#) and part of it was filling a data grid with an embedded xml file.
Although I've now found a way to make this work, i am still confused as to to theory behind it. And I'd like to stop and make sure i fully understand it before i continue with this project.
The code that i have working currently is;
XmlDataDocument myXML = new XmlDataDocument();
StringReader mytempXML = (new StringReader(BasicTest.Properties.Resources.myxml));
myXML.DataSet.ReadXml(mytempXML);
What is confusing to me is that before this solution, I was trying the below;
myXML.DataSet.ReadXml(BasicTest.Properties.Resources.myxml);
and it wasn't working. However using the full file path (like below) was working.
myXML.DataSet.ReadXml("C:/..etc../myxml.xml");
The Question I have is: why is a StringReader required for the ReadXml method if you're reading from a resource, but using a full file path works without?
If anyone could provide an explanation, that would be great.
Thanks.
This is because the ReadXml method takes a string. That string must be the name of a file. It cannot be XML. If you pass it a string that is XML, it will think that is the name of the file! It doesn't have the smarts to look at the string and ask "Is this string XML, or is it a file name?" and figure that out.
// Summary:
// Reads XML schema and data into the System.Data.DataSet using the specified
// file.
//
// Parameters:
// fileName:
// The filename (including the path) from which to read.
public XmlReadMode ReadXml(string fileName);
By wrapping the XML in a stringreader or a stream or something, you are calling a different overload, that expects XML instead of a file name.

Read an XML file from http address

I need to read an xml file using c#/.net from a source like so: https://10.1.12.15/xmldata?item=all
That is basically just an xml file.
StreamReader does not like that.
What's the best way to read the contents of that link?
The file looks like so:
- <RIMP>
- <HSI>
<SBSN>CZ325000123</SBSN>
<SPN>ProLiant DL380p Gen8</SPN>
<UUID>BBBBBBGGGGHHHJJJJ</UUID>
<SP>1</SP>
<cUUID>0000-000-222-22222-333333333333</cUUID>
- <VIRTUAL>...
You'll want to use LINQ to XML to process the XML file. The XDocument.Load Method supports loading an XML document from an URI:
var document = XDocument.Load("https://10.1.12.15/xmldata?item=all");
Another way to do this is using the XmlDocument class. A lot of servers around the world are still running .Net Framework < 3.0 so it's good to know that this class still exists alongside XDocumentin case you're developing an application that will be run on a server.
string url = #"https://10.1.12.15/xmldata?item=all";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(url);
Maybe the correct answer must starting by reading the initial question about how to "Read an XML file from a URL (or in this case from a Http address)".
I think that can be the best for you see the next easy demos:
(In this case XmlTextReader but today you can use XmlReader instead of XmlTextReader)
http://support.microsoft.com/en-us/kb/307643
(Parallel you could read this documentation too).
https://msdn.microsoft.com/en-us/library/system.xml.xmlreader(v=vs.110).aspx
regards

Loading a custom section from XML

I want to add an ability to an application that I'm developing for accessing configuration.
The application will search by default in the app.config file for a section that I give it.
If it was not found in the app.config, it will look for it in the DB, in a specific table that has the following columns:
SectionType, SectionName, SectionData
The SectionData column is a text column, that contains the data of the section in XML format (exactly like it should be in the app.config file)
I can take the SectionData content, but I can't load it into the custom ConfigurationSection, like I would have done if it was in the app.config file:
var mySectionObj = ConfigurationManager.GetSection("myCustomSection");
To simplify, my question is actually how can I get the custom ConfigurationSection object from a XML string instead of a configuration file?
You could load the string into an XDocument object and read it from there.
I don't think that's possible at all - with the ConfigurationManager class from .NET, it is as far as I know not even possible to open whatever file you want - you are restricted to the app.config file. Reading configuration data from another source than a file? No can do.
You can either analyse the XML-String yourself (with "XmlDocument.LoadXml(string)") or you modify the app.config file and read it again.
The question would be: Why wouldn't there be the CustomSection in the config file? Should this be considered an error (then updating the config file would be best, I think). Or is it intended, that some config files don't have the CustomSection?
If the settings may be in the XML-File, adding the setting to the file would be like this:
XmlDocument appconfig = new XmlDocument();
appconfig.Load("[config_filename]");
XmlNode root = appconfig.DocumentElement;
XmlDocument mysection = new XmlDocument();
mysection.LoadXml([SectionData]);
XmlNode customSection = mysection.DocumentElement;
XmlNode tempNode = appconfig.ImportNode(customSection, true);
root.AppendChild(tempNode);
appconfig.Save("[config_filename]");
...
var mySectionObj = ConfigurationManager.GetSection("myCustomSection");
if this is not desirable, I see two possibilities:
First:
Do it nevertheless: Change the .config file, read it, and then change it back.
(or copy the file, change the original, read it, delete it, rename the copy back to the original name).
This way is not nice, it's somehow impure, in my opinion, but it has some great advantages: It works and it is easy to maintain.
Second:
Load your XML string into a XmlDocument: XmlDocument.LoadXml(xmlstring)
Then analyse the xmldocument, with "doc.ChildNodes" or "doc.SelectNodes(xpath)" or "doc.SelectSingleNode(xpath)".
This will be much more work, especially since you will have to maintain to routines to get the configuration settings into your project, so I would not recommend this method. Strongly not recommend.

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