How to get element by element from XmlDocument - c#

I was able to get my first element from this list
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetITARListResponse xmlns="http://tempuri.org/">
<GetITARListResult>
<ClassificationCode>
<code>dsd</code>
<description>toto</description>
<legislation>d/legislation>
</ClassificationCode>
<ClassificationCode>
<code>dsd</code>
<description>tata</description>
<legislation>dsd</legislation>
</ClassificationCode>
<ClassificationCode>
<code>code2</code>
<description>dsds</description>
<legislation>dsd</legislation>
</ClassificationCode>
by writing
XDocument result = new XDocument();
result = ExportControl.ResultXML;
var codes = HttpContext.Current.Server.MapPath("~/XML_Templates/codes.xml");
dynamic root = new ExpandoObject();
XmlToDynamic.Parse(root, xDoc.Elements().First());
var result = xDoc.Descendants(XNamespace.Get("http://tempuri.org/") + "code").First();
which get the the first code "dsd". But what if I want a foreach and get all the code? or what if I want a certain code ? for example
var result = xDoc.Descendants(XNamespace.Get("http://tempuri.org/") + "code")[2]

.Net framework provides a set of tools you can use to move over an XML file:
XmlReader: this class reads xml files in hierarchical manner and only forward
without cached.
XmlWriter: this class writes in xml files only forward without
cached.
XmlDocument: it helps you to navigate and edit small documents as it's
slower than XmlReader/Writer. It uses XmlNode objects to move through your document and perform changes (attributes). After editing your you can save. A nifty way to navigate is by using XPath
(query language for xml).
XPathNvigator: class offers an easy way to navigate through an XML document.
In your case, my recommendation is to implement a couple of methods one for iteration and one for location of a particular node with XmlReader and XPath respectively.
Update: the XML example is malformed here:
<legislation>d/legislation>
This shows you an example to read the file:
using System;
using System.Xml;
namespace XMLTest
{
class Program
{
static void Main(string[] args)
{
string xml = #"<?xml version=""1.0"" encoding=""utf-8"" ?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<soap:Body>
<GetITARListResponse xmlns=""http://tempuri.org/"">
<GetITARListResult>
<ClassificationCode>
<code>dsd</code>
<description>toto</description>
<legislation>d</legislation>
</ClassificationCode>
<ClassificationCode>
<code>dsd</code>
<description>tata</description>
<legislation>dsd</legislation>
</ClassificationCode>
<ClassificationCode>
<code>code2</code>
<description>dsds</description>
<legislation>dsd</legislation>
</ClassificationCode>
</GetITARListResult>
</GetITARListResponse>
</soap:Body>
</soap:Envelope>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var items = doc.GetElementsByTagName("ClassificationCode");
foreach (var item in items)
{
Console.WriteLine(((System.Xml.XmlElement)(item)).InnerText.ToString());
}
Console.ReadLine();
}
}
}
// OUTPUT
// dsdtotod
// dsdtatadsd
// code2dsdsdsd

Your code sample is returning the First item merely because you're calling First() method. In order to loop through all codes you can skip the call and you will get an IEnumerable. Then you can loop like this:
var codes = result.Descendants(XNamespace.Get("http://tempuri.org/") + "code");
foreach (var codeElement in codes)
{
Console.WriteLine(codeElement.Value);
}
// prints:
// dsd
// dsd
// code2
To access them by index you can use ElementAt like this:
var someCode = codes.ElementAt(1);
Console.WriteLine(someCode.Value); // prints dsd
Or you can filter by name like this:
var code2 = codes.Where(c => c.Value == "code2").First();
Console.WriteLine(code2.Value); // prints code2

Related

Removing parentnode but not childnodes XmlElement

I'm in a situation where i need to get rid of my parentnode, but not my childnodes.
Here is how it loooks:
<?xml version="1.0" encoding="utf-8"?>
<ns0:MisMessage>
<mislife>
<party/>
<datetime>2018-06-04T09:35:33</datetime>
<insurance">
<number>123</number>
<amount>3</amount>
<indicator></indicator>
<text>asd</text>
</insurance>
</mislife>
<ns0:Message/>
</ns0:MisMessage>
And here is how i want it to look after i'm done.
<mislife>
<party/>
<datetime>2018-06-04T09:35:33</datetime>
<insurance">
<number>123</number>
<amount>3</amount>
<indicator></indicator>
<text>asd</text>
</insurance>
</mislife>
Is there any easy way to do this? I have tried and tried and tried. I have been looking all over the internet and i can't find out how to do it. The thing i want to remove will always be named ns0: in the beggning. Can i do it by removeing with substrings? THANKS!
I solved it like below, i converted the XMLDocument to XDocument and then used the descendants. Just like #bommelding showed in his example. Thank you all!
var xDocument = ToXDocument(xmlDocument);
if (xDocument != null)
{
var mislife = xDocument.Descendants("mislife").FirstOrDefault();
if (mislife != null)
{
return mislife;
}
}
public static XDocument ToXDocument(XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
XDocument doc = XDocument.Load(fileName);
XElement data = doc
.Descendants("mislife") // find your target
.Single(); // be brave, there should be exactly 1
data.Save(otherFileName); // saves with document <? ... ?>
Simple way with Linq (remember to add using System.Xml.Linq;):
string testxml = #"
<?xml version=""1.0"" encoding=""UTF-8""?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>";
XDocument doc = XDocument.Parse(testxml).Descendants().First().Document;
doc will be your xml without the root element
XDocument can load from files with
XDocument.Load("path");
or read XML like I did with
Xml.Parse("<xml....>");
and have also other options.
Result is:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

Extract data from xml string

Let's say I have an xml string:
<?xml version="1.0" encoding="UTF-8"?>
<Return version="1.0">
<File>1</File>
<URL>2</URL>
<SourceUUID>1191CF90-5A32-4D29-9F90-24B2EXXXXXX0</SourceUUID>
</Return>
and I want to extract the value of SourceUUID, how?
I tried:
XDocument doc = XDocument.Parse(xmlString);
foreach (XElement element in doc.Descendants("SourceUUID"))
{
Console.WriteLine(element);
}
If all you want is the content of the SourceUUID element, and there's only going to be 1 in the XML, you can do this:
XDocument doc = XDocument.Parse(xmlString);
var value = doc.Descendants("SourceUUID").SingleOrDefault()?.Value;
If there are going to be more than one, you can do this:
var values = doc.Descendants("SourceUUID").Select(x => x.Value);
This gives you an enumerable of strings that are the text values of the elements.

How to remove xmlns tag from xml element using c#

I want to remove this xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0" from all xml element except root tag. xml element using C#. I have written below code to get to as xml form. But unable to remove xmlns tag from xml element.
<?xml version="1.0" encoding="utf-16"?>
<QualityDeviationCaseType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CaseID xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0">2</CaseID>
<Description xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0">Air filter is not present</Description>
<StartDate xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0">0001-01-01T00:00:00</StartDate>
<LastUpdated xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0">0001-01-01T00:00:00</LastUpdated>
</QualityDeviationCaseType>
After remove xmlns="http://www.AB.com/BC/QualityDeviationCase/1_0" this tag, my result should return like this as below-
<?xml version="1.0" encoding="utf-16"?>
<QualityDeviationCaseType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CaseID>2</CaseID>
<Description>Air filter is not present</Description>
<StartDate>0001-01-01T00:00:00</StartDate>
<LastUpdated>0001-01-01T00:00:00</LastUpdated>
</QualityDeviationCaseType>
My C# Code, I am getting xml result from my XSD file.
connection.Open();
adapter = new SqlDataAdapter(sql, connection);
adapter.Fill(dt);
myTestTable = dt.Clone();
DataRow[] orderRows = dt.Select();
XmlDocument xmlDoc = new XmlDocument();
QualityDeviationCaseType oQualityDeviationCaseType = new QualityDeviationCaseType();
foreach (DataRow row in orderRows)
{
oQualityDeviationCaseType = new QualityDeviationCaseType();
oQualityDeviationCaseType.CaseID = row[0].ToString();
oQualityDeviationCaseType.Description = row[3].ToString();
}
using (StringWriter stringwriter = new System.IO.StringWriter())
{
XmlSerializer ser = new XmlSerializer(typeof(QualityDeviationCaseType));
ser.Serialize(stringwriter, oQualityDeviationCaseType);
sampleChannel.Publish(stringwriter.ToString());
//This line of code sending my xml file to IBM WMQ.
}
As per my above code, My result is coming with xml tag for each lement. I want to remove from element tag using c#.
The xmlns attribute has important semantics in XML: it puts all elements in the default namespace http://www.AB.com/BC/QualityDeviationCase/1_0.
I am not familiar with C# specifically, however: removing it implies reasoning at the semantic level rather than syntactic.
Concretely, it should be done by removing the namespace of all elements in the XML document being exported, or not putting them in any namespace in the first place. If the C# library is complete, it should provide a way to do so.
Did you try Regex?
using System.Text.RegularExpressions;
...
string pattern = #"xmlns=""[a-zA-Z0-9:\/._]{1,}""";
using (StringWriter stringwriter = new System.IO.StringWriter())
{
XmlSerializer ser = new XmlSerializer(typeof(QualityDeviationCaseType));
ser.Serialize(stringwriter, oQualityDeviationCaseType);
string s = stringwriter.ToString();
Match m = Regex.Match(s,pattern);
if(m.Success)
s=s.Replace(m.Value, "");
sampleChannel.Publish(s);
//This line of code sending my xml file to IBM WMQ.
}
I'm not that familiar with XmlSerializer, but that should work I think. Match will only find anything beginning with 'xmlns="' and ending with '"'.

How to create a dictionary and store values for the values in c#

I want to create a dictionary for the following xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<groups>
<group>
<data>Open</data>
<aggregation>5</aggregation>
</group>
</groups>
I want my dictionary to get the values as:
Open,5
Please note that 'Open' is fetched from <data>Open</data> and '5' is fetched from <aggregation>5</aggregation>.
My current code is as follows:
foreach (XmlNode group in Bugsagg)
{
XmlNode data = group.SelectSingleNode(".//data");
XmlNode aggregate = group.SelectSingleNode(".//aggregation");
if (Dict_Aggregate.ContainsKey(data.InnerText))
{
Dict_Aggregate[data.InnerText]++;
}
else
{
Dict_Aggregate.Add(data.InnerText, 1);
}
I am not getting the desired response. Please suggest where i am doing wrong.Thanks
Use XElement and LINQ to XML.
You should add
using System.Xml;
using System.Xml.Linq;
on top of your code. Then use the following
string xml = #"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><groups><group><data>Open</data><aggregation>5</aggregation></group></groups>";
XElement xe = XElement.Parse(xml);
Dictionary<string,string> d =
xe.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);
Some people might also suggest to use an XDocument as you provide a fully qualified xml with declaration etc:
XDocument xd = XDocument.Parse(xml);
Dictionary<string,string> d =
xd.Root.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);

xml c# read and write helper

I have the following examples, and the c# is just my draft. Can you show me how to call the xml file and read there so I can get the value
public static ArrayList GetLocationLiabilityAmount()
{
ArrayList al = new ArrayList();
string selectedValue = Library.MovieClass.generalLibailityLocationLiability;
if (!String.IsNullOrEmpty(selectedValue))
{
if (option from xml == selectedValue)
{
al.Add(minvalue);
al.Add(maxvalue);
}
return al;
}
else
{
return null;
}
}
XML:
<?xml version="1.0" encoding="utf-8" ?>
<AccidentMedicalCoverage>
<coverage option="1" value="10000" showvalue="$10,000 per person"></coverage>
<coverage option="2" value="25000" showvalue="$25,000 per person"></coverage>
<coverage option="3" value="50000" showvalue="$50,000 per person"></coverage>
</AccidentMedicalCoverage>
The question is not too clear but this is what I assume you want:
Given an option if you want to get the value from the XML this is one way you can do it:
XmlDocument xDoc = new XmlDocument();
xDoc.Load("c:\\xmlfile\\coverage.xml");
// Select the node with option=1
XmlNode node = xDoc.SelectSingleNode("/AccidentMedicalCoverage/coverage[#option='1']");
// Read the value of the Attribute 'value'
var value = node.Attributes["value"].Value;
I prefer linq to Xml. There are two ways given to get the data into an XDocument shown below and then a basic query into the data
//var xml = File.ReadAllText(#"C:\data.xml");
var xml = GetFile();
//var xDoc = XDocument.Load(#"C:\data.xml"); Alternate
var xDoc = XDocument.Parse(xml);
var coverages = xDoc.Descendants("coverage");
coverages.Select (cv => cv.Attribute("showvalue").Value)
.ToList()
.ForEach(showValue => Console.WriteLine (showValue));
/* Output
$10,000 per person
$25,000 per person
$50,000 per person
*/
...
public string GetFile()
{
return #"<?xml version=""1.0"" encoding=""utf-8"" ?>
<AccidentMedicalCoverage>
<coverage option=""1"" value=""10000"" showvalue=""$10,000 per person""></coverage>
<coverage option=""2"" value=""25000"" showvalue=""$25,000 per person""></coverage>
<coverage option=""3"" value=""50000"" showvalue=""$50,000 per person""></coverage>
</AccidentMedicalCoverage>";
}

Categories

Resources