I have the following xml in XmlDocument. I am trying to extract the className from it.
<Registration className="Eng" type="DirectRegistration" state="Activated" xmlns="http://xyz/Registration">
<Fields>
<Field type="abc" value="123456" />
<Field type="xyz" value="789" />
</Fields>
</Registration>
I have tried the following code but its not giving me className.
var xmlNode = xmlDoc.DocumentElement;
Can anyone help me to get the value of className out.
Many Thanks
You were almost there:
var className = xmlDoc.DocumentElement.GetAttribute("className");
xmlDoc.DocumentElement gives you the whole element; GetAttribute pulls an individual named attribute from it.
Try using this:
// Trying to parse the given file path to an XML
XmlReader firstXML = XmlReader.Create(XMLPath);
firstXML.ReadToFollowing("Registration");
firstXML.MoveToAttribute("className");
var res = firstXML.Value;
res will hold "className" value.
you can also use xPath to retrieve the attribute
string className = xmlDocument.SelectSingleNode("//Registration/#className").Value;
Related
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
From the following XML, I want to find a value based on the Employer.
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Details>
<Employer>Taxes</Employer>
<Adr>
<Strt>Street</Strt>
<Twn>Town</Twn>
</Adr>
</Details>
<DetailsAcct>
<Recd>
<Payroll>
<Id>9</Id>
</Payroll>
</Recd>
<br>
<xy>A</xy>
</br>
</DetailsAcct>
</Document>
the C# code I applied is
detail = root.SelectSingleNode($"//w:Document//w:Employer[contains(text(), 'Taxes']/ancestor::Employer",nsmgr);
But it gives me an invalid token error.
What am I missing?
The error was due to [contains(...], notice closing parentheses is missing. And since you want to return Employer element, no need for ancestor::Employer here :
//w:Document//w:Employer[contains(., 'Taxes')]
If the XML posted resembles structure of the actual XML (except the namespaces), better to use more specific XPath i.e avoid using costly // :
/w:Document/w:Details/w:Employer[contains(., 'Taxes')]
An alternative is to use LINQ to XML.
If the XML is in a string:
string xml = "<xml goes here>";
XDocument document = XDocument.Parse(xml);
XElement element = document.Descendants("Employer").First();
string value = element.Value;
If the XML is in a .xml file:
XDocument document = XDocument.Load("xmlfile.xml");
XElement element = document.Descendants("Employer").First();
string value = element.Value;
You can also find an employer element with a specific value, if that's what you need:
XElement element = document.Descendants("Employer").First(e => e.Value == "Taxes");
Note: this will throw an exception if no element is found with the specified value. If that is not acceptable, then you can replace .First(...) with .FirstOrDefault(...) which will simply return null if no element is found.
I have a service which returns the below xml as string.I am using Xdocument parse method and XmlDocument load methods to convert the string to xml. but i want to parse and get the status and i_numer which i need to use for further processing.can some one point me in right direction or give some hints.below is the xml i am using.
i tried the innerxml property from the Xdocument and XmlDocument which is returning the whole "" element and this is not what i needed.
<Report>
<Incidentreport Company="company1" ID="sample">
<status i_number="12345678" status="sucessful" />
</Incidentreport>
</Report>
The following should work:
string str = [string of xml goes here];
string i_number = string.Empty;
XmlDocument doc = new XmlDocument();
doc.Load(str);
XmlNode node = doc.SelectSingleNode("//status");
i_number = node.Attributes["i_number"].Value;
You can use SelectSingleNode() which accept XPath parameter to get the target attribute value in one go * :
var raw = #"<Report>
<Incidentreport Company='company1' ID='sample'>
<status i_number='12345678' status='sucessful' />
</Incidentreport>
</Report>";
var doc = new XmlDocument();
doc.LoadXml(raw);
var result = doc.SelectSingleNode("/Report/Incidentreport/status/#i_number");
Console.WriteLine(result.Value);
dotnetfiddle demo
*) notice how XML attribute can be referenced by using #attribute_name syntax in XPath
have an XML file like this:
<VS>
<Fields>
<Field Id="$1*">Column1</Field>
<Field Id="$2*">Column2</Field>
<Field Id="$3*">Column3</Field>
</Fields>
</VS>
When I use LINQ to XML using the following statement:
XDocument doc = XDocument.Parse(s);
var q = doc.Descendants("Fields").ToList();
I get a single entry in list as Column1Column2Column3, whereas I want it as 3 separate entities like Column1, Column2, Column3.
Can anyone help?
Use Field instead of Fields:
var q = doc.Descendants("Field").ToList();
you should use XElement.Parse(BuildNode.InnerXml) instead of just passing the raw property in.
Check This
Just used the following code which returned list of strings.
var q = doc.Descendants("Field").Select(x => x.Value);
Thanks for all your suggestions!
I'm getting a NullReferenceException upon trying to read an attribute of an xml-file - what attribute to read from what element is defined by user-input.
The StackTrace keeps redirecting me to this line (marked)
XmlDocument _XmlDoc = new XmlDocument();
_XmlDoc.Load(_WorkingDir + "Session.xml");
XmlElement _XmlRoot = _XmlDoc.DocumentElement;
XmlNode _Node = _XmlRoot.SelectSingleNode(#"group[#name='" + _Arguments[0] + "']");
XmlAttribute _Attribute = _Node.Attributes[_Arguments[1]]; // NullReferenceException
Where did I miss the point? What Reference is missing here? I can't figure it out...
Edit: The element exists and so does the attribute (including a value)
<?xml version="1.0" encoding="utf-8"?>
<session>
<group name="test1" read="127936" write="98386" />
<group name="test2" read="352" write="-52" />
<group name="test3" read="73" write="24" />
<group name="test4" read="264524" write="646243" />
</session>
Further explanation: The _Arguments[] is a splitted array of the user input. The user e.g. inputs test1_read - that is splitted to _Arguments[0] = "test" and _Arguments[1] = "read"
Would you not be better using the XmlElement.GetAttribute method? This means you can then use the XmlElement.HasAttribute to do a check before you try to access it. This would definitely avoid the NullReference.
Sample
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(_WorkingDir + "Session.xml");
XmlElement xmlRoot = xmlDoc.DocumentElement;
foreach(XmlElement e in xmlRoot.GetElementsByTagName("group"))
{
// this ensures you are safe to try retrieve the attribute
if (e.HasAttribute("name")
{
// write out the value of the attribute
Console.WriteLine(e.GetAttribute("name"));
// or if you need the specific attribute object
// you can do it this way
XmlAttribute attr = e.Attributes["name"];
Console.WriteLine(attr.Value);
}
}
Also I would suggest you have a look at using LinqToXml when parsing Xml documents in .NET.
In absence of the XML file you are parsing, I would guess that maybe in the XPath expression, you need to specify //group instead of simply group.