Loading a custom section from XML - c#

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.

Related

XML Edit to file using C#

I am working on a WPF application and I have a simple XML file that I am parsing using 'XmlDocument' and is working fine for the readinh part.
I want the use to be able to add, edit or delete any node and save these changes to the file.
I tried using 'XElement' but it seems to change the instance itself and not the file.
My XML file looks something like this:
<Configuration>
<A_0.04_5>
<ML407Configuration>
<AM_Amp>10</AM_Amp>
<AMRJ_Amp>10</AMRJ_Amp>
<FM_Freq>20</FM_Freq>
<FM_Phase_Shift>20</FM_Phase_Shift>
</ML407Configuration>
<BertConfiguration>
<BERT_LR>25.78125</BERT_LR>
<BERT_PRBS>7</BERT_PRBS>
<BERT_Scaling>1000</BERT_Scaling>
</BertConfiguration>
</A_0.04_5>
<B_1.333_0.15>
<ML407Configuration>
<AM_Amp>10</AM_Amp>
<AMRJ_Amp>10</AMRJ_Amp>
<FM_Freq>20</FM_Freq>
<FM_Phase_Shift>20</FM_Phase_Shift>
</ML407Configuration>
<BertConfiguration>
<BERT_LR>25.78125</BERT_LR>
<BERT_PRBS>7</BERT_PRBS>
</BertConfiguration>
</B_1.333_0.15>
<C_4_0.05>
<ML407Configuration>
<BUJ_LR>25</BUJ_LR>
<BUJ_Pattern>7</BUJ_Pattern>
<PM_BUJ_Amp>7</PM_BUJ_Amp>
<BUJ_Amp>80</BUJ_Amp>
</ML407Configuration>
<BertConfiguration>
<BERT_LR>25.78125</BERT_LR>
<BERT_PRBS>7</BERT_PRBS>
</BertConfiguration>
</C_4_0.05>
</Configuration>
What I tried is the following:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"/Configuration.xml";
XElement xml = XElement.Load(filePath);
// This seems to remove the node from xml instance and not from the file
// Should I save the file again or is there another way to do it
// Same applies for add and edit
xml.Elements("C_4_0.05").Remove();
I have seen a lot of similar questions but I don't know if any of them change directly to the file or not
XElement.Load loads an XML structure from a file into memory. Any changes you make to that structure are also done in memory. If you want to write those changes back to a file (technically called serialization) you need to call XElement.Save.

Creating embedded resource in C# class library if it doesn't exist

I have an issue with a class library; I am preparing a library with an interface that represents a specific data storage signature. The purpose is to use the interface as a basis for implementing a number of specific classes storing configuration information in different formats (text files, xml files, etc.) while retaining the same usage profile to the application using it. I have a problem, though. In this case I am trying to embed an xml file as a resource - this file is one type of format to store configuration data. The file is located as an embedded resource in a subfolder to the project, as shown in the attached illustration.
In the following code snippet it is shown how I have implemented the functionality until now.
public ConfigInfoXmlSource()
{
if (!string.IsNullOrEmpty(Settings.Default.CurrentConfigFile))
FileNameAndPath = Settings.Default.CurrentConfigFile;
else
FileNameAndPath = DefaultConfigFileName + DefaultFileExtension;
// Prepare XML.
System.Reflection.Assembly a = Assembly.GetExecutingAssembly();
XmlDocument doc = new XmlDocument();
Stream manifestResourceStream =
a.GetManifestResourceStream("TestTool.Config.Config1.xml");
if (manifestResourceStream == null)
{
// ???
}
...
doc.Load(manifestResourceStream);
...
}
In the section marked "Prepare XML" I am trying to read a stream from the embedded resource. After the reading, it is tested whether a stream was indeed created. If the file is found, the manifestResourceStream will contain the xml data - so far so good. The problem arises if the file for some reason has been accidentally deleted - in that case I want to create a new file as an embedded resource to replace the deleted file. That is supposed to happen in the conditional in the part shown as "???".
I have tried everything I could think of, searched Google for answers, etc. - to no avail.
Does anyone have a clue to how this is accomplished? Any help will be greatly appreciated.
Thanks in advance.
Best regards.
If you have a embedded resource,it is built into your binaries.It is not an physical file,rather something which is present inside the built file(dll in this case).So,once it is included,I do not think it can ever be deleted. As per my knowledge embedded resource can only be set while building your project binaries and you can not explicitly do it at runtime as it is not needed due to reasons mentioned above.

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

Categories

Resources