Select attribute from xml element - c#

I'm trying to select an attribute from my root node but i keep getting a null exception on the select part.
What's the correct way of getting the value of my attribute?
The value i am trying to get value of the attribute: SymbolicName
The xml document:
<Bundle xmlns="urn:uiosp-bundle-manifest-2.0" Name="ContactUsPlugin" SymbolicName="ContactUsPlugin" Version="1" InitializedState="Active">
<Activator Type="ContactUsPlugin.Activator" Policy="Immediate" />
<Runtime>
<Assembly Path="bin\ContactUsPlugin.dll" Share="false" />
</Runtime>
<Functionality>
<Controller>About</Controller>
<View>Index</View>
</Functionality>
<Scripts>
<Script version="1">
<Location>E:\Git Projects\Kapsters\Plugins\ContactUsPlugin\Sql\Sql1.txt</Location>
</Script>
<Script version="2">
<Location>E:\Git Projects\Kapsters\Plugins\ContactUsPlugin\Sql\Sql1.txt</Location>
</Script>
</Scripts>
</Bundle>
I tried:
string widgetCodeName =
(from db in ManifestDocument.Elements() select db.Attribute("SymbolicName").Value).First();
string widgetCodeName =
(from db in ManifestDocument.Descendants() select db.Element("Bundle").Attribute("SymbolicName").Value).First();
string widgetCodeName =
(from db in ManifestDocument.Element("Bundle").Attributes() where db.Name == "SymbolicName" select db.Value).First();

According to the xml that you have, the bundle tag is the root node. Try:
string widgetCodeName = ManifestDocument.Root.Attribute("SymbolicName").Value;

All this examples work depending on if you need only the value or the XAttribute itself:
XDocument ManifestDocument = XDocument.Load("YourXmlFile.xml");
var myquery = ManifestDocument.Elements().Attributes("SymbolicName").First();//the XAttribute
string myvalue = ManifestDocument.Root.Attribute("SymbolicName").Value;//the value itself
var secondquery = ManifestDocument.Descendants().Attributes("SymbolicName").First();//another way to get the XAttribute
The last one (secondquery) will get SymbolicName attribute even if also defined in another node if you remove the .First().

if this is your entire XML then you can get it with the code below.
XElement elem = XElement.Parse(xmlStr);
string val = elem.Attribute("SymbolicName").Value;
where xmlStr is your XML. if the attribute is missing then the Attribute method will return null so make sure you test for null before accessing the Value property

Your Bundle element has a xml namespace. You need to specify it:
XNamespace ns = "urn:uiosp-bundle-manifest-2.0";
string widgetCodeName = (string)ManifestDocument
.Element(ns + "Bundle")
.Attribute("SymbolicName");
Or, if Bundle is your Root element you can do:
string widgetCodeName = (string)ManifestDocument
.Root
.Attribute("SymbolicName");

Try this :
XNamespace ns = "urn:uiosp-bundle-manifest-2.0";
XDocument xd = XDocument.Load(#"xmlDocument");
var assemblyLocation = from a in xd.Descendants(ns + "Bundle")
select new
{
Path = a.Element(ns + "Runtime").Element(ns + "Assembly").Attribute("Path").Value,
};

Related

C# XElement Get Attribute with a Namespace

I have a number of XElements, but their "href" attribute has a namespace. When I try to get it, it returns null.
<link xlink:href="The/href" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="a/location">A value</link>
I have tried:
XElement linkEl = doc.Root.Element("link");
string hrefValue = linkEl.Attribute("href").Value //null;
I have also tried adding the namespace to the "href" like "xlink:href" in Attribute(), but this results in an error. Anyone know how to perform this magic?
Try this one:
XDocument doc = XDocument.Parse(#"<link xlink:href=""The/href"" xmlns:xlink=""http://www.w3.org/1999/xlink"" xmlns=""a/location"">A value</link>");
XNamespace ab = "http://www.w3.org/1999/xlink";
string hrefValue = doc.Root.Attribute(ab + "href").Value;
For your sample xml you can't find your element by using its Name it must be the LocalName of the element.
To get element by LocalName here is the sample:
var linkElement = doc.Root.Elements().Where(e => e.Name.LocalName == "link").FirstOrDefault();
var linkAttribute = linkElement.Attributes().Where(a => a.Name.LocalName == "href").FirstOrDefault();
var hrefValue = linkAttribute.Value;

Xdocument parse file and read values

I have the below sample XML , I need to retrive the values for the following two fields txJu and ddate.I also have the code but it is giving null expection
<Doc id="580171" ddate="2019-06-21" >
<ref dtRef="2019-08-21">
<dr>
<cr>
<pj>
<pr>
<dDup txJu="0.00" txFi="0.00" txcOp="0.00" />
<comp txJu="12.96" txFi="2.45" txOp="0.00" />
</pr>
</pj>
</cr>
</dr>
</ref>
</Doc>
var xdoc = XDocument.Load(file);
string txJu = xdoc.Root.Element("comp").Attribute("txJu").Value;
string ddate = xdoc.Root.Element("Doc").Attribute("ddate").Value;
There are a couple of issues with your code. Your Root element doesn't contain comp node, Doc element is root itself, string ddate = string value = ... is invalid C# declaration.
You can modify your code per following
var compElement = xdoc.Root?.DescendantsAndSelf("comp").FirstOrDefault();
string txJu = compElement?.Attribute("txJu")?.Value;
string ddate = xdoc.Root?.Attribute("ddate")?.Value;
string value = ddate;
Use DescendantsAndSelf method to get a collection of filtered comp elements and use first of them. Access ddate attribute directly in Root element. Use null-conditional operator ? to avoid possible null reference exceptions

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 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.

Getting decendant node that contains ":"?

I have loaded a XML into a XDocument that looks something like this :
<MyXML xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MyApp.Client.Main.GUI.Report">
<Wrapper xmlns:d2p1="http://schemas.datacontract.org/2004/07/MyApp.Business.Entity">
<d2p1:_MultipelAttributId>156</d2p1:_MultipelAttributId>
</Wrapper>
</MyXML>
Now I need to get the value of _MultipelAttributId but when stating this :
XElement element = (from cml2 in doc.Descendants("d2p1:_MultipelAttributId") select cml2).FirstOrDefault();
I get exception about the ":"?
So how do I get the valiue?
XNamespace ns = "http://schemas.datacontract.org/2004/07/MyApp.Business.Entity";
var element = xDoc.Descendants(ns + "_MultipelAttributId").FirstOrDefault();
The element name you're querying is not correct. Try this:
XElement element = (
from cml2 in doc.Descendants()
where cml2.Name.LocalName == "_MultipelAttributId"
select cml2).FirstOrDefault();
This MSDN article explains well how to work with namespaces in Linq to XML
http://msdn.microsoft.com/en-us/library/bb669152.aspx
XNamespace d2p1 = "http://schemas.datacontract.org/2004/07/MyApp.Business.Entity";
XElement multipelAttributId = doc.Descendants(d2p1 + "_MultipelAttributId").FirstOrDefault();
Notice that you can seamly create an XNamespace or an XName from a string because Microsoft have writen inplicit casts for these types.

Categories