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>
Related
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.
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
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
);
<Employees>
<Product_Name>
<hello1>product1</hello1>
<hello2>product2</hello2>
<hello3>product3</hello3>
<hello4>product4</hello4>
</Product_Name>
<product_Price>
<hello1>111</hello1>
<hello2>222</hello2>
<hello3>333</hello3>
<hello4>444</hello4>
</product_Price>
</Employees>
is it possible to convert the following XML to the XML shown below using C#. I tried using remove function but it didn't work. I also tried to get the value of root node. Didn't work
<Product_Name>
<hello1>product1</hello1>
<hello2>product2</hello2>
<hello3>product3</hello3>
<hello4>product4</hello4>
</Product_Name>
<product_Price>
<hello1>111</hello1>
<hello2>222</hello2>
<hello3>333</hello3>
<hello4>444</hello4>
</product_Price>
If you just want to fetch the inner xml,you can use the XmlReader's ReadInnerXml.The innerXML is fetched as a string(skipping the root node).
var xmlReader = XElement.Load("data.xml").CreateReader();
xmlReader.MoveToContent();
string innerXml = xmlReader.ReadInnerXml();
If you have access to Linq to XML, you should you XDocument.
caveat: I believe your xml is malformed - you should have something like:
<?xml version="1.0" encoding="utf-8"?>
Add the first xml tag to the xml.
string xml = #"<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Product_Name>
<hello1>product1</hello1>
<hello2>product2</hello2>
<hello3>product3</hello3>
<hello4>product4</hello4>
</Product_Name>
<product_Price>
<hello1>111</hello1>
<hello2>222</hello2>
<hello3>333</hello3>
<hello4>444</hello4>
</product_Price>
</Employees>";
XDocument xDoc = XDocument.Parse(xml);
// get the elements
var rootElements = xDoc.Root.Elements();
Alternatively, you can load the xml from a file:
XDocument xDoc = XDocument.Load("xmlFile.xml");
You can store it as XmlNodeList to be well-formed. Here's a working example of how to do it:
XmlDocument xml= new XmlDocument();
xml.LoadXml(#"<Employees>
<Product_Name>
<hello1>product1</hello1>
<hello2>product2</hello2>
<hello3>product3</hello3>
<hello4>product4</hello4>
</Product_Name>
<product_Price>
<hello1>111</hello1>
<hello2>222</hello2>
<hello3>333</hello3>
<hello4>444</hello4>
</product_Price>
</Employees>");
var nodeList = xml.SelectNodes("Employees");
foreach (XmlNode node in nodeList)
{
Console.WriteLine(node.InnerXml); //this will give you your desired result
}
I have this 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>
<GetSKUsPriceAndStockResponse xmlns="http://tempuri.org/">
<GetSKUsPriceAndStockResult>
<RequestStatus>
<DateTime>2/28/2012 5:28:05 PM</DateTime>
<Message>S200</Message>
</RequestStatus>
<SKUsDetails>
<SKUDetails>
<SKU>N82E16834230265</SKU>
<Model>X54C-NS92</Model>
<Stock>true</Stock>
<Domain>newegg.com</Domain>
<SalePrice>439.99</SalePrice>
<ShippingCharge>0.00</ShippingCharge>
<Currency>USD</Currency>
</SKUDetails>
</SKUsDetails>
</GetSKUsPriceAndStockResult>
</GetSKUsPriceAndStockResponse>
</soap:Body>
</soap:Envelope>
How can I read <SKUDetails> Node using XPath?. What will be XNamespace for above XML?
Manipulate XML data with XPath and XmlDocument (C#)
or
its better to use LINQ to XML as your are using .net 4.0 and there is no need to learn XPath to traverse the xml tree.
Not sure about the xpath expression but you can code like this
string fileName = "data.xml";
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
// Compile a standard XPath expression
XPathExpression expr;
expr = nav.Compile("/GetSKUsPriceAndStockResponse/GetSKUsPriceAndStockResult/SKUsDetails/SKUDetails");
XPathNodeIterator iterator = nav.Select(expr);
try
{
while (iterator.MoveNext())
{
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
as #Kirill Polishchuk answered - SKUDetails is defined in http://tempuri.org/
he shows you how to get using XDocument
you can use alsow XmlDocument like this:
var dom = new XmlDocument();
dom.Load("data.xml");
var mgr = new XmlNamespaceManager(dom.NameTable);
mgr.AddNamespace("a", "http://tempuri.org/");
var res = dom.SelectNodes("//a:SKUDetails", mgr);
SKUsDetails is defined in http://tempuri.org/ namespace. You can use this code to select SKUsDetails using XPath:
var doc = XDocument.Load("1.xml");
var mgr = new XmlNamespaceManager(doc.CreateReader().NameTable);
mgr.AddNamespace("a", "http://tempuri.org/");
var node = doc.XPathSelectElement("//a:SKUsDetails", mgr);
To select SKUDetails use: //a:SKUsDetails/a:SKUDetails