Using XDocument to convert selected node to string - c#

I have the following XML sample.
<?xml version="1.0" encoding="utf-8"?>
<GlobalResponses>
<Filters>
<FilterId>11</FilterId>
<FilterId>5</FilterId>
<FilterId>10</FilterId>
</Filters>
<Responses>
<Response>
<Name>Bob</Name>
</Response>
<Response>
<Name>Jim</Name>
</Response>
<Response>
<Name>Steve</Name>
</Response>
</Responses>
</GlobalResponses>
Using XDocument, how can I get only the <Responses> parent and also child nodes, and convert them to a string variable. I looked at XDocument Elements and Descendants, but by calling oXDocument.Descendants("Responses").ToString(); didn't work.
Do I have to iterate over all of the XElements checking each one and then appending to a string variable ?

Function Descendants returns enumeration of XElement, so you need to select specific element.
If you want to get XML element with all the child nodes, you can use:
// assuming that you only have one tag Responses.
oXDocument.Descendants("Responses").First().ToString();
The result is
<Responses>
<Response>
<Name>Bob</Name>
</Response>
<Response>
<Name>Jim</Name>
</Response>
<Response>
<Name>Steve</Name>
</Response>
</Responses>
If you want to get child nodes and concatenate them to single string you can use
// Extract list of names
var names = doc.Descendants("Responses").Elements("Response").Select(x => x.Value);
// concatenate
var result = string.Join(", ", names);
The result is Bob, Jim, Steve

The Descendants() method takes input the element name and it will return you a collection of nodes and from those you then further need to get the elements you are interested in.
You can use linq with XDocument to extract the information. For example, the following code with extract the Name element value from each Response node and prints out :
var nodes = from response in Doc.Descendants("Response")
select response.Element("Name").Value;
foreach(var node in nodes)
Console.WriteLine(node);
Here above Doc.Descendants("Response") will fetch all the <Response> elements and then we are using response.Element("Name") to fetch the <Element> tag for each <Response> element and then using .Value property we get the value between the tag.
See this working DEMO fiddle.

Related

How to Get XML Element by It's 'Value' using XML C# SDK

I have this snippt of XML
<unit class="xxx.xxx.xxx" id="382">
<customId>000</customId>
<description>kg</description>
<key>22452</key>
<Description>Kilogramm</Description>
</unit>
how to get the node 'unit' or parnet of the key element using the value of an element. For instance
i have the value of key element above [22452] and it's Uniqe inside the xml-File.
what i am trying to do getting value of customid [000] of that specific tag.
what i did:
var doc = new XmlDocument();
doc.Load(stream); // stream from xml-file
var key = doc.SelectSingleNode(//key/[text()='" + 22452+ "']"); // that i am not sure about it.
var customId = key.InnerText("customId");
For this kind of query you could either find the node and than navigate to the parent.
Or use XPath:
var unitElemnt = doc.SelectSingleNode("//unit[key = '22452']");
(Assuming I've remembered the XPath to match an element's text content correctly.)
This gets a reference to the <unit> element, by using a relative path to the <key> element in the predicate of the XPath expression.
Generally better to avoid // in XPath for performance, but would need full document structure to do that.
For this you can use Linq to Xml queries.
XElement units = XElement.Load("./Test.xml");
XElement unit = (from item in units.Descendants("unit")
where item.Element("key").Value == "22455"
select item).FirstOrDefault();
string customId = unit.Element("customId").Value;
supposing your xml file look like :
<?xml version="1.0" encoding="utf-8"?>
<units>
<unit class="xxx.xxx.xxx" id="385">
<customId>003</customId>
<description>kg</description>
<key>22455</key>
<Description>Kilogramm</Description>
</unit>
<unit class="xxx.xxx.xxx" id="386">
<customId>004</customId>
<description>kg</description>
<key>22456</key>
<Description>Kilogramm</Description>
</unit>
</units>
for more reading check Microsoft Linq to Xml Docs

Remove specific node from xml

Here is my xml
<result>
<client></client>
<message></message>
<record>
<message></message>
</record>
</result>
I want to remove the "message" node which is right below "result"
when I tried to remove it by using below code:
responseXml.Descendants().Where(e => e.Name == "client" || e.Name == "message").Remove();
It is removing "message" which is under "record" but I don't want this.
I want to remove only "message" under "result"
Expected xml:
<result>
<client></client>
<record>
<message></message>
</record>
</result>
Please suggest me here.
Descendants() will return all elements (children and grand-children etc.), while Elements() will only return immediate children.
responseXml.Root.Elements().Where(e => e.Name == "message").Remove();
You could probably use the shorter .Element("message") syntax, but be aware that this method only returns the first element found. If you have more than one <message> it wont return/remove them all.
void Main()
{
string xml =#"
<result>
<client></client>
<message></message>
<record>
<message></message>
</record>
</result>";
XElement root = XElement.Parse(xml);
root.Element("message").Remove();
}
Removes exact element "message" directly under root node.
You can call Element(name), which returns a single XElement (calling Elements or Descendants returns a IEnumerable<XElement>):
responseXml.Root.Element("message").Remove();

LINQ TO XML retrieving Child Element Value

I have the following XML
<ABC xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId>
<IdValue>123</IdValue>
</ReceiptId>
<ClientOrderId>
<IdValue>345</IdValue>
</ClientOrderId>
<AccessPoint>
<Description>My Description</Description>
</AccessPoint>
<ABCStatus>
<Status>Error</Status>
<Details>ERRORS:
Talent is already in an active process for this opening.
</Details>
<StatusDate>2015-08-05</StatusDate>
</ABCStatus>
</ABC>
I am trying to retrieve the element value 345 nested in IdValue and ClientOrderId
I have used the Linq to xml code in C# to retrieve the value with no luck
XDocument XMLResults = XDocument.Parse(sResult);
var sClientOrderID =
from nodeAElem in XMLResults.Root.Elements("ABC")
from nodeA1Elem in nodeAElem.Elements("ClientOrderId")
from nodeA11Elem in nodeA1Elem.Elements("IdValue")
select nodeA11Elem.Value;
also need to retrieve the Status Elements value which is Error for the above xml.
Any help is greatly appreciated
Your XML document is using a namespace, you have to use it in your query to make it work.
Root already brings you to ABC element, so you don't have to call Elements("ABC")
You're looking for single value, so you probably want to use Element instead of Elements.
var ns = (XNamespace)"http://ns.hr-xml.org/2007-04-15";
var sClientOrderID = (int)XMLResults.Root
.Element(ns + "ClientOrderId")
.Element(ns + "IdValue");

How to iterate XML-formatted string through "foreach" loop in C#?

I have string in XML format with the following content:
<?xml version="1.0" encoding="Windows-1251" ?>
<Operation>
<PersonOperation>
<Name>John Smith</Name>
<Phone>79161234586</Phone>
<City>Glasgow</City>
<Date>2014-02-03</Date>
<OperationType>Join</OperationType>
<Amount>9000.00</Amount>
</PersonOperation>
<PersonOperation>
<Name>Bill Satly</Name>
<Phone>78263211334</Phone>
<City>London</City>
<Date>2014-07-10</Date>
<OperationType>Stock</OperationType>
<Amount>3000.00</Amount>
</PersonOperation>
How can I iterate this string through "foreach" loop in C# and check if the value of OperationType node is equal to "Join"?
Load the string into an XmlDocument and use the SelectNodes() method with the appropriate XPath query.
Query to iterate:
"Operation/PersonOperation"
You can do it with a LinqToXml query, like this:
var result = document.Root.Elements()
.Where(b => b.Element("OperationType").Value == "Join");

Why xmlDocument.Select return zero count

i am trying to access a node for xml
<?xml version="1.0" encoding="utf-8"?>
<LinkAnalysis>
<ImgInfo>
<Number>xyz</Number>
<ImgPath>D:\Projects\VERBALinks\VERBALinks\bin\Debug\LA_img\xyz.png</ImgPath>
</ImgInfo>
</LinkAnalysis>
using following code
var nodes = doc.SelectNodes(String.Format("/LinkAnalysis/ImgInfo[#Number=\"{0}\"]", "xyz"));
But it returns me zero count. Why??
<Number> is an element, not an attribute, so your XPath expression is wrong.
Try:
String.Format("/LinkAnalysis/ImgInfo[Number/text()='{0}']", "xyz")

Categories

Resources