How to get value of element with XDocument and Linq to XML - c#

I want to collect the RequestID element with the namespace, but I do not know how.
this.XmlString = "<?xml version=\"1.0\"
encoding=\"utf-8\"?><MethodNameRq xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><RequestID
xmlns=\"http://Mynamespace\">573-348976-428697-346</RequestID ></MethodNameRq>";
var doc = XDocument.Parse(this.XmlString);
this.RequestId = (string)doc.Descendants().Where(n => n.Name
== "RequestID ").FirstOrDefault();
This collects an empty string for RequestID. It does work if the string has no namespaces included. Does anyone know how I can collect the RequestID element?

you need to specify the namespace of your element
XNamespace ns = "http://Mynamespace";
this.RequestId = (string)doc.Descendants(ns + "RequestID").FirstOrDefault();

Related

LINQ xml finding nodes returns null

I try to parse an xml file with XDocument class, with criteria that if the child node matches a given string, its parent node is selected.
<SalesQuotes xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://api.some.com/version/1">
<Pagination>
<NumberOfItems>2380</NumberOfItems>
<PageSize>200</PageSize>
<PageNumber>1</PageNumber>
<NumberOfPages>12</NumberOfPages>
</Pagination>
<SalesQuote>
<Guid>825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a</Guid>
<LastModifiedOn>2018-01-09T12:23:56.6133445</LastModifiedOn>
<Comments>Please note:
installation is not included in this quote
</Comments>
</SalesQuote>
</SalesQuotes>
I tried using
var contents = File.ReadAllText(path: "test1.xml");
var doc = XDocument.Parse(contents);
var root = doc.Root;
var sq = root.Elements("SalesQuote");//return null
var theQuote = root.Elements("SalesQuote").Where(el => el.Element("Guid").Value == "825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a");//return null
var theAlternativeQuote =
from el in doc.Descendants("SalesQuote").Elements("Guid")
where el.Value == "825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a"
select el;//return null
I can't seem to find what's wrong.
Any help is much appreciated! Thanks.
You ignored the namespace bro.
Do remove the xmlns attribute in your XML or try this:
var contents = File.ReadAllText("XMLFile1.xml");
var doc = XDocument.Parse(contents);
var root = doc.Root;
XNamespace ns = "http://api.some.com/version/1";
var sq = root.Descendants(ns + "SalesQuotes"); //return null
var theQuote = root.Elements(ns + "SalesQuote")
.Where(el => el.Element(ns + "Guid").Value == "825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a"); //return null
var theAlternativeQuote =
from el in doc.Descendants(ns + "SalesQuote").Elements(ns + "Guid")
where el.Value == "825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a"
select el; //return null
If you are not too concerned about keeping your current implementation, you could consider using a Typed DataSet and load your XML into fully typed, structured objects.
Querying those objects with Linq will be more straight forward than what I see in your current implementation.
You might also find this useful:
SO Question: Deserialize XML Document to Objects
yap, you're missing the namespace that you can grab with document.Root.GetDefaultNamespace()
// Load
var document = XDocument.Parse(xml);
var xmlns = document.Root.GetDefaultNamespace();
// Find
var query = from element in document
.Descendants(xmlns + "SalesQuote")
.Elements(xmlns + "Guid")
where element.Value == "825634b9-28f5-4aa7-98e7-5e4a4ed6bc6a"
select element;

Get Atttribute value from XDocument

I am trying to get the ResponseCode attribute value out of this XML.
The XML is an XDocument
<IDMResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="1" xmlns="http://www.fake.org/namespace/">
<ARTSHeader>
<Response ResponseCode="Rejected">
<RequestID>1</RequestID>
<BusinessError Severity="Error">
<Code>IdmInvalidUserNamePasswordLoginProvided</Code>
<Description>Invalid username or password, if problem persists, please contact Administrator</Description>
</BusinessError>
</Response>
</ARTSHeader>
</IDMResponse>
With XPath: (No error checks done)
XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("def", "http://www.fake.org/namespace/");
XDocument doc = XDocument.Parse(xml);
string code =
doc
.XPathSelectElement(#"/def:IDMResponse/def:ARTSHeader/def:Response", nsm)
.Attribute("ResponseCode")
.Value;
foreach (XElement el in doc.Root.Elements())
{
if(el.Name.ToString() == "ARTSHeader")
foreach(XElement ell in el.Elements())
{
if(ell.Name.ToString() == "Response")
string responseCode = ele.Attribute("ResponseCode").Value;
}
}
Does this work for you? I dont know the whole structure of your xml so you might need to go deeper into the nested xml to get to Response first
One possible way :
.....
XNamespace ns = "http://www.fake.org/namespace/";
string responseCode = (string)doc.Descendants(ns+"Response")
.First()
.Attribute("ResponseCode");
Console.WriteLine(responseCode);
You could try this one out, I haven`t tested so you might need to rearrange some structure
XDocument doc1 = XDocument.Parse(soapResult);
XNamespace ns1 = "http://www.fake.org/namespace/";
var items = doc1.Descendants(ns1 + "ARTSHeader").Descendants(ns1 + "Response").First().Attribute("ResponseCode").Descendants(ns1 + "BusinessError").First().Attribute("Severity")
.Select((x) => new
{
Code = x.Element(ns1 + "Code").Value,
Description = x.Element(ns1 + "Description").Value,
});

get xml node value from xml string

I have xml which contain xml namespace. i need to get value from its xml node
<personxml:person xmlns:personxml="http://www.your.example.com/xml/person" xmlns:cityxml="http://www.my.example.com/xml/cities">
<personxml:name>Rob</personxml:name>
<personxml:age>37</personxml:age>
<cityxml:homecity>
<cityxml:name>London</cityxml:name>
<cityxml:lat>123.000</cityxml:lat>
<cityxml:long>0.00</cityxml:long>
</cityxml:homecity>
Now i want to get value of tag <cityxml:lat> as 123.00
Code :
string xml = "<personxml:person xmlns:personxml='http://www.your.example.com/xml/person' xmlns:cityxml='http://www.my.example.com/xml/cities'><personxml:name>Rob</personxml:name><personxml:age>37</personxml:age><cityxml:homecity><cityxml:name>London</cityxml:name><cityxml:lat>123.000</cityxml:lat><cityxml:long>0.00</cityxml:long></cityxml:homecity></personxml:person>";
var elem = XElement.Parse(xml);
var value = elem.Element("OTA_personxml/cityxml:homecity").Value;
Error i am getting
The '/' character, hexadecimal value 0x2F, cannot be included in a name.
You need to use XNamespace. For example:
XNamespace ns1 = "http://www.your.example.com/xml/person";
XNamespace ns2 = "http://www.my.example.com/xml/cities";
var elem = XElement.Parse(xml);
var value = elem.Element(ns2 + "homecity").Element(ns2 + "name").Value;
//value = "London"
Create XNamespace using a string that contains the URI, then combine the namespace with the local name.
For more information, see here.
You are better off using a XmlDocument to navigate your xml.
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode node = doc.SelectSingleNode("//cityxml:homecity/cityxml:lat");
string latvalue = null;
if (node != null) latvalue = node.InnerText;
The error I got with your code was that there needs to be a namespace to parse the XML properly
Try :
XNamespace ns1 = "http://www.your.example.com/xml/cities";
string value = elem.Element(ns1 + "homecity").Element(ns1 + "name").Value;
I would still advice using XDocuments to parse if possible, but the above is fine if your way is a must.

Inserting and removing nodes from an XML namespace

I'm trying to replace a node's name but I'm getting the following error "The reference node is not a child of this node". I think I know why this is happening but can't seem to work around this problem. Here is the XML:
<payload:Query1 xmlns="" xmlns:payload="" xmlns:xsi="" xsi:schemaLocation="">
<payload:QueryId>stuff</payload:QueryId>
<payload:Data>more stuff</payload:Data>
</payload:Query1>
And here is the C# bit:
doc.Load(readStream);
nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("payload", "location");
XmlNode Query1 = doc.SelectSingleNode("//payload:Query1", nsmgr);
public XmlDocument sendReply(args)
{
XmlNode newNode = doc.CreateElement("payload:EditedQuery");
Query.InsertBefore(newNode, Query1);
Query.RemoveChild(Query1);
return doc;
}
I'm trying to replace "Query" with "EditedQuery" but his doesn't work.
If you can use .Net 3.5 LINQ to XML,
XElement root = XElement.Load(readStream);
XNamespace ns = "http://somewhere.com";
XElement Query1 = root.Descendants(ns + "Query1").FirstOrDefault();
// should check for null first on Query1...
Query1.ReplaceWith(new XElement(ns + "EditedQuery"));
Or, if you don't know the namespace, or don't want to hard-code it:
XElement root = XElement.Load(readStream);
XElement Query1 = root.Descendants()
.FirstOrDefault(x => x.Name.Localname == "Query1");
// should check for null first on Query1...
Query1.ReplaceWith(new XElement(Query1.Name.Namespace + "EditedQuery"));
See Jon Skeet's reason why to use LINQ to XML here over older API's.

Select Node Type From XML document

Hi i have a scenario where i want to search the node in xml file and identify the type of file.
XDocument xDococumnetObj = XDocument.Load(filePath);
XElement presentationElement=
xDococumnetObj.Descendants()
.Where(x => x.Name.LocalName.Equals("collegge"))
.FirstOrDefault();
I have written query which returns me collegge node. But i just want to identify the type of document it is. I want to identify the document whether it contains {"Collegge","University","Company","Banking"} in single query and return its Type only.
string[] docTypes = {"Collegge", "University", "Company", "Banking"};
XDocument xdoc = XDocument.Load(filePath);
var docType = docTypes.FirstOrDefault(type =>
xdoc.Descendants().Any(n => n.Name.LocalName == type.ToLower()));
UPDATE: If all elements declared in same namespace, you can use following code to avoid traversing all elements from files
string[] docTypes = {"Collegge", "University", "Company", "Banking"};
XDocument xdoc = XDocument.Load(filePath);
XNamespace ns = "http://www.foo.org/2013/bar";
var docType = docTypes.FirstOrDefault(type => xdoc.Descendants(ns + type).Any());

Categories