How to read header line of XML file [duplicate] - c#

This question already has answers here:
Reading a value from root node XML
(4 answers)
Closed 9 years ago.
Need to write C# how to read configuration's version value = 1.0.1.2 in xml? I want to get this value then assign it to a string variable. Your example code would be much apprecaited. Thanks!
<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0.1.2" createDate="2013-07-04T10:00:00">
<config>
.
.
.
.
</config>
</Configuration>

You can use LINQ to XML (this will load whole xml file into memory):
XDocument xdoc = XDocument.Load(path_to_xml);
var version = (string)xdoc.Root.Attribute("version");
Or use XmlReader to avoid loading file into memory:
using(XmlReader reader = XmlReader.Create(path_to_xml))
{
reader.MoveToContent();
var version = reader.GetAttribute("version")
}

Related

XML Node with text and nodes together [duplicate]

This question already has answers here:
Can a XML element contain text and child elements at the same time?
(2 answers)
Closed 7 months ago.
I have a XML document looking like this:
<?xml version="1.0" encoding="utf-8"?>
<root>
<node>some Text
<subnode>other text</subnode>
</node>
</root>
Now I want to get the content of node without the subnode- in my example only "some Text".
I tried XmlNode.InnerText (gives me the whole text with subnodes) and XmlNode.Value (gives me null)
Now I wonder, if this is valid XML at all and if yes how to get it in C#?
Yes, it is indeed a valid XML. You can use Linq to XML to retrieve the text. Some Text is notated as TextNode you can verify it with NodeType property.
using System.Xml.Linq;
var xmlText = #"<?xml version=""1.0"" encoding=""utf - 8""?>
<root>
<node> some Text
<subnode> other text </subnode>
</node>
</root>";
var xml = XElement.Parse(xmlText);
var textNode = (xml.FirstNode as XElement).FirstNode;
Console.WriteLine(textNode.ToString());
Fiddle

How to force prefix in all XmlElements in XmlDocument? [duplicate]

This question already has answers here:
Adding a prefix to an xml node
(2 answers)
Rewrite XMLDocument to use namespace prefix
(3 answers)
Closed 2 years ago.
I need to create XML like below. Because of retardation of target system. I need to have prefixes in front of all nodes. All nodes need to have "ns0" prefix present.
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>1</ns0:Date>
<ns0:Field1>2</ns0:Field1>
<ns0:Field2>3</ns0:Field2>
</ns0:MainMessage>
</ns0:RootElement>
There is no schema. I need to add nodes depending on user input. This is sample of the code that add nodes to "ns0:MainMessage" element:
XmlDocument xml = new XmlDocument();
xml.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><ns0:RootElement xmlns:ns0=\"http://top-secret\"><ns0:MainMessage></ns0:MainMessage></ns0:RootElement>");
XmlElement mainMessageElement = xml.DocumentElement["ns0:MainMessage"];
XmlElement newElement = mainMessageElement.OwnerDocument.CreateElement("Date");
newElement.Prefix = "ns0";
newElement.InnerText = "thisIsTest;
mainMessageElement.AppendChild(newElement);
This produces output like this:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<Date>thisIsTest</Date>
</ns0:MainMessage>
</ns0:RootElement>
While I need output where "Date" element is prefixed with "ns0" like "ns0:Date". Like so:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>thisIsTest</ns0:Date>
</ns0:MainMessage>
</ns0:RootElement>
How to force this Date element to have ns0 prefix?
You need to actually qualify the element into the correct namespace:
var newElement = mainMessageElement.OwnerDocument.CreateElement(
"Date", "http://top-secret");
newElement.Prefix = "ns0";
Note, however, that it may be easier to do all of this with the XDocument API.

How to read a value from a xml file

I have the following XML File,
<?xml version="1.0"?>
<MainClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<Settings xsi:type="FileModel">
<Name>FileRepository</Name>
<IsActive>true</IsActive>
<IsHidden>false</IsHidden>
</Settings>
<Settings xsi:type="ServerModel">
<Name>DelRep</Name>
<IsActive>false</IsActive>
<IsHidden>false</IsHidden>
</Settings>
</Items>
<DirectoryPath>D:\MainFolder</DirectoryPath>
</MainClass>
This XML File stored above in a string as string wholeContent = File.ReadAllText(this.FilePath);
where this FilePath has a valid path to the location of the file .
the wholeContent stores the entire XML which I later use but now I have the necessity to obtain the path stores as a string within the <DirectoryPath> . Is there a way I can do this using wholeContent or what would be the appropriate approach ?
I would recommend not to load the XML document as string, use the types provided by .NET, such as XDocument.
Accessing the elements and their values gets very easy that way:
XDocument document = XDocument.Load(this.FilePath);
var element = document.Root.Elements().Single(x => x.Name == "DirectoryPath");
var directoryPath = element.Value;

How to comment out line by line of a XML file in C# with System.XML

I need to comment and uncomment a XML node with child nodes in a file using System.XML.
Starting XML:
<?xml version="1.0" encoding="utf-8"?>
<test>
<!--comment...-->
<childTest>
<childchildTest>5<childchildTest/>
</childTest>
</test>
Commenting the whole node wouldn't be a problem and easy to achieve like in this example. But my problem is that I've already got some comments inside the node and nested comments aren't allowed per XML rules.
That means I would have to comment out line by line of the XML file so I would not destroy the XML file structure with nested comments.
Desired output:
<?xml version="1.0" encoding="utf-8"?>
<!-- <test> -->
<!--comment...-->
<!-- <childTest> -->
<!-- <childchildTest>5<childchildTest/> -->
<!-- </childTest> -->
<!-- </test> -->
Is it possible to achieve this with System.XML or would I have to do this with regex for example?
Assuming you have this XML well-organised in a file (meaning each node is on its own line, as you presented) you could use this one-liner:
File.WriteAllLines("path to new XML file", File.ReadAllLines("path to XML file").Select(line => line.Trim().StartsWith("<!--") ? line : $"<!--{line}-->"));
This part line.Trim().StartWith("<!--") ? line : $"<!--{line}-->" means if line is a comment (starts with <!--) then don't comment it, otherwise, do it.
In my opinion, there is no framework method which provides this functionality.
You can read XML file lines and then create new files which has comments for every line as shown in below code.
// Create a string array with the lines of text
string[] lines = File.ReadAllLines(path-of-file);
// Write the string array to a new file named "ouput.xml".
using (StreamWriter outputFile = new StreamWriter(Path.Combine(mydocpath,"output.xml"))) {
foreach (string line in lines)
outputFile.WriteLine("<!--" + line + "-->");
}

how to extract xml attributes values based on a condition using Xpath or/and C# [duplicate]

This question already has answers here:
How do I read and parse an XML file in C#?
(12 answers)
Closed 9 years ago.
From the XML below how can we extract values of speed 'key values' based on the given deliveryFormat. e.g. The speed values for deliveryFormat key=1 are 2,3,4 and for deliveryFormat key=4 are 5,6,4
The following code gives me the keys for the availableFormats and based on these keys I want to extract the speed key values
XmlDocument results = new XmlDocument();
results.LoadXml(theModel.SearchLog.AvailabilityXML);
var AvailableFormats = results.SelectNodes("//apiResponse/availableFormats/availableFormat/deliveryFormat/#key");
XML
<?xml version="1.0" encoding="UTF-8"?>
<apiResponse>
<availableFormats>
<availableFormat availabilityDate="2014-01-31">
<deliveryFormat key="1">Encrypted Download</deliveryFormat>
<deliveryModifiers/>
<availableSpeeds>
<speed key="2">2 Hours</speed>
<speed key="3">24 Hours</speed>
<speed key="4">4 Days</speed>
</availableSpeeds>
<availableQuality>
<quality key="1">Standard</quality>
<quality key="2">High</quality>
</availableQuality>
</availableFormat>
<availableFormat availabilityDate="2014-01-31">
<deliveryFormat key="4">Paper</deliveryFormat>
<deliveryModifiers/>
<availableSpeeds>
<speed key="5">2 Hours</speed>
<speed key="6">24 Hours</speed>
<speed key="4">4 Days</speed>
</availableSpeeds>
<availableQuality>
<quality key="1">Standard</quality>
<quality key="2">High</quality>
</availableQuality>
</availableFormat>
</availableFormats>
</apiResponse>
Please try the following xpath. It gives you all speed for deliveryFormat 1. You can change the key value as needed.
//availableFormat[deliveryFormat/#key='1']//speed
Or, if you want just the speed keys:
//availableFormat[deliveryFormat/#key='1']//speed/#key
EDIT: Fixed xpath conditional

Categories