Save the same element from XML file as an array C# - c#

it could be a silly question, but i want ta ask, how can I save the same element from an .XML file with different content as an array.
Example XML:
<ithem>
<description>description1</description>
<description>description2</description>
<description>description3</description>
</ithem>
then string [] descriptions will be
descriptions[0] = "description1";
descriptions[1] = "description2";
descriptions[2] = "description3";
Please help!

Using LINQ to XML it would be:
XElement root = XElement.Load(xmlFile);
string[] descriptions = root.Descendants("description").Select(e => e.Value).ToArray();
or
string[] descriptions = root.Element("ithem").Elements("description").Select(e => e.Value).ToArray();

Use XmlDocument to parse the XML :
var map = new XmlDocument();
map.Load("path_to_xml_file"); // you can also load it directly from a string
var descriptions = new List<string>();
var nodes = map.DocumentElement.SelectNodes("ithem/description");
foreach (XmlNode node in nodes)
{
var description = Convert.ToString(node.Value);
descriptions.Add(description);
}
And you get it as an array from:
descriptions.ToArray();

Related

Error while defining XPathSelectElement c#

I have a complex XML file where I want to retrieve different values from the different Set tag.At the end, i need to take the values to a CSV file.
Please see the xml file format
I am trying to retrieve the value of
<szItemID>3268750004533</szItemID> from the first set
<lMerchandiseStructureID>40</lMerchandiseStructureID> from the second set
<szDesc>PHG VIANDE SECHEE DE</szDesc> from the third set
<dPackingUnitPriceAmount>75</dPackingUnitPriceAmount> from the fourth tag
I have tried to retrieve the first element through the below code but getting an error
NullReferenceException was unhandled
Object reference not set to an instance of an object
Code
XmlDocument document = new XmlDocument();
document.Load(#"D:\\xml_1.xml");
string myXmlString = document.OuterXml.ToString();
XElement xml = XElement.Parse(myXmlString);
Console.WriteLine(string.Format("{0}",xml.XPathSelectElement("/UpdateDB/Transaction/Insert/Set/szItemID").Value));
Please help
StringBuilder dataToBeWritten = new StringBuilder();
var doc = XDocument.Load(#"D:\xml_2.xml");
foreach (var trans in doc.Descendants("Transaction"))
{
var val3 = (string)doc.Descendants("Set").Elements("szItemID").First();
var val4 = (string)doc.Descendants("Set").Elements("lMerchandiseStructureID").First();
var val5 = (string)doc.Descendants("Set").Elements("szName").First();
var val6 = (string)doc.Descendants("Set").Elements("lRetailStoreID").First();
var val7 = (string)doc.Descendants("Set").Elements("bIsContract").First();
dataToBeWritten.Append(val3);
dataToBeWritten.Append(",");
dataToBeWritten.Append(val4);
dataToBeWritten.Append(",");
dataToBeWritten.Append(val5);
dataToBeWritten.Append(",");
dataToBeWritten.Append(val6);
dataToBeWritten.Append(",");
dataToBeWritten.Append(val7);
dataToBeWritten.Append(",");
dataToBeWritten.Append(Environment.NewLine);
}
Console.WriteLine(dataToBeWritten.ToString());
Console.ReadLine();
var testpath = #"D:\\Lutchmee2.csv";
File.WriteAllText(testpath, dataToBeWritten.ToString());
Your XElement is UpdateDB, so from that context there is no child UpdateDB. You'd have to amend your query to:
/Transaction/Insert/Set/szItemID
That said, it's unclear why you're loading the document into the DOM, converting it to a string and than parsing to an XElement. Just load into an XDocument and use your original query:
var doc = XDocument.Load(#"D:\xml_1.xml");
var val = (string) doc.XPathSelectElement("/UpdateDB/Transaction/Insert/Set/szItemID");
Or better still, use LINQ to XML as it was intended:
var val = (string) doc.Descendants("Set").Elements("szItemID").First()

How to not deserialize contents of node

Say I have the following xml:
<Samples>
<Sample>
<SomeStuff>
<SomMoreStuff>.. </SomeMoreStuff>
</SomeStuff>
</Sample>
<Sample>
<SomeStuff>
<SomMoreStuff>.. </SomeMoreStuff>
</SomeStuff>
</Sample>
</Samples>
How can I deserilaize this but have all text inside of < Sample > remain as a string? I dont want to parse the contents of Sample
[XmlRoot(ElementName="Samples")]
public class Samples {
[XmlElement("Sample")]
public string[] Items{ get; set; }
}
I want to end of with a list like
[
"<Sample><SomeStuff><SomMoreStuff>.. </SomeMoreStuff></SomeStuff></Sample>"
"<Sample><SomeStuff><SomMoreStuff>.. </SomeMoreStuff></SomeStuff></Sample>"
]
You might want to load your Schema into the XmlDocument class and extract the inner or outer XML from it as a string.
One example could be:
var xdoc = new XmlDocument();
xdoc.LoadXml(MySchema);
var sampleNode = xdoc.SelectNodes("//sample");
var sampleText = sampleNode.ToString();
// or
var sampleText2 = sampleNode.Item(0).OuterXml;
Use debugging to check the actual value of the node, to get the right string as output.
List example:
var xdoc = new XmlDocument();
xdoc.LoadXml(MySchema);
var sampleNode = xdoc.SelectNodes("//sample");
var sampleList = new List<string>();
foreach (XmlNode item in sampleNode)
{
sampleList.Add(item.OuterXml); // or InnerXml - whatever value it is you need.
}

Adding info to a xml file

I have a XML file which contains about 850 XML nodes. Like this:
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>
........ 849 more
And I want to add a new Childnode inside each and every Node. So I end up like this:
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
<Description>TestDescription</Description>
</NameValueItem>
........ 849 more
I've tried the following:
XmlDocument doc = new XmlDocument();
doc.Load(xmlPath);
XmlNodeList nodes = doc.GetElementsByTagName("NameValueItem");
Which gives me all of the nodes, but from here am stuck(guess I need to iterate over all of the nodes and append to each and every) Any examples?
You need something along the lines of this example below. On each of your nodes, you need to create a new element to add to it. I assume you will be getting different values for the InnerText property, but I just used your example.
foreach (var rootNode in nodes)
{
XmlElement element = doc.CreateElement("Description");
element.InnerText = "TestDescription";
root.AppendChild(element);
}
You should just be able to use a foreach loop over your XmlNodeList and insert the node into each XmlNode:
foreach(XmlNode node in nodes)
{
node.AppendChild(new XmlNode()
{
Name = "Description",
Value = [value to insert]
});
}
This can also be done with XDocument using LINQ to XML as such:
XDocument doc = XDocument.Load(xmlDoc);
var updated = doc.Elements("NameValueItem").Select(n => n.Add(new XElement() { Name = "Description", Value = [newvalue]}));
doc.ReplaceWith(updated);
If you don't want to parse XML using proper classes (i.e. XDocument), you can use Regex to find a place to insert your tag and insert it:
string s = #"<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>";
string newTag = "<Description>TestDescription</Description>";
string result = Regex.Replace(s, #"(?<=</Code>)", Environment.NewLine + newTag);
but the best solution is Linq2XML (it's much better, than simple XmlDocument, that is deprecated at now).
string s = #"<root>
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>
<NameValueItem>
<Text>Test2</Text>
<Code>Test2</Code>
</NameValueItem>
</root>";
var doc = XDocument.Load(new StringReader(s));
var elms = doc.Descendants("NameValueItem");
foreach (var element in elms)
{
element.Add(new XElement("Description", "TestDescription"));
}
var text = new StringWriter();
doc.Save(text);
Console.WriteLine(text);

Get node property of XmlDocument in C#

I'm using this xml structure:
<park>
<car title="Ferrari" available="true">
<url>http://www.ferrari.com/</url>
</rss>
</park>
And this is my code in C#:
XmlDocument doc = new XmlDocument();
doc.Load("Settings.xml");
XmlNodeList list = doc.SelectNodes("/park/car");
foreach (XmlNode item in list)
{
string x = item["#title"].InnerText;
}
I just want to get "title" property but i can't get it working. I'm using "#" but without success.
Try this code:
string x = item.Attributes["title"].Value;
I suggest you to use LINQ to XML for parsing xml:
var xdoc = XDocument.Load("Settings.xml");
var titles = xdoc.XPathSelectElements("//park/car")
.Select(c => (string)c.Attribute("title"));
Or without XPath:
var titles = xdoc.Descendants("park")
.Elements("car")
.Select(c => (string)c.Attribute("title"));

Get certain xml node and save the value

Considering the following XML:
<Stations>
<Station>
<Code>HT</Code>
<Type>123</Type>
<Names>
<Short>H'bosch</Short>
<Middle>Den Bosch</Middle>
<Long>'s-Hertogenbosch</Long>
</Names>
<Country>NL</Country>
</Station>
</Stations>
There are multiple nodes. I need the value of each node.
I've got the XML from a webpage (http://webservices.ns.nl/ns-api-stations-v2)
Login (--) Pass (--)
Currently i take the XML as a string and parse it to a XDocument.
var xml = XDocument.Parse(xmlString);
foreach (var e in xml.Elements("Long"))
{
var stationName = e.ToString();
}
You can retrieve "Station" nodes using XPath, then get each subsequent child node using more XPath. This example isn't using Linq, which it looks like you possibly are trying to do from your question, but here it is:
XmlDocument xml = new XmlDocument();
xml.Load(xmlStream);
XmlNodeList stations = xml.SelectNodes("//Station");
foreach (XmlNode station in stations)
{
var code = station.SelectSingleNode("Code").InnerXml;
var type = station.SelectSingleNode("Type").InnerXml;
var longName = station.SelectSingleNode("Names/Long").InnerXml;
var blah = "you should get the point by now";
}
NOTE: If your xmlStream variable is a String, rather than a Stream, use xml.LoadXml(xmlStream); for line 2, instead of xml.Load(xmlStream). If this is the case, I would also encourage you to name your variable to be more accurately descriptive of the object you're working with (aka. xmlString).
This will give you all the values of "Long" for every Station element.
var xml = XDocument.Parse(xmlStream);
var longStationNames = xml.Elements("Long").Select(e => e.Value);

Categories

Resources