How to get value of an XML node? - c#

For the life of me I have not been able to extract the SourcePartyName from this XML document:
<ns0:Visit xmlns:ns0="http://Co.Burgers.Ues">
<ns0:SourcePartyName>NDHARY</ns0:SourcePartyName>
</ns0:Visit>
Using Scott's solution, I've been able to extract the namespace info; however, after dozens of attempts at monkeying with XDocument / XElement, I have not been able to get the desired NDHARY value.
Attempts have included:
xdoc.Descendants(ns + "SourcePartyName").FirstOrDefault()?.Value;
and
xdoc.Element(ns + "SourcePartyName").Value;
How do you get the value of a node from an XDocument?

When using an XDocument you have to go via its Root property.
String xml = #"
<ns0:Visit xmlns:ns0=""http://Co.Burgers.Ues"">
<ns0:SourcePartyName>NDHARY</ns0:SourcePartyName>
</ns0:Visit>
";
XDocument xdoc = XDocument.Parse(xml);
XNamespace ns = "http://Co.Burgers.Ues";
String sourcePartyName = (String)xdoc.Root.Element(ns + "SourcePartyName");

Related

xdocument adding xdocument

I am doing something wrong can't grab shipmentreceiptlineitem to add to first document, do I need to add a namespace?
XDocument xdoc = XDocument.Load("FirstPart.xml");
xdoc.Root.Add(XDocument.Load("RepeatingPart.xml").Element("ShipmentReceiptLineItem").Elements());
xml to grab from:
<tns:ShipmentReceiptNotification xmlns:dl="urn:rosettanet:specification:domain:Logistics:xsd:schema:02.18"
xmlns:tns="urn:rosettanet:specification:interchange:ShipmentReceiptNotification:xsd:schema:02.01">
<tns:ShipmentReceiptLineItem>
</tns:ShipmentReceiptLineItem>
</tns:ShipmentReceiptNotification>
Yes, you need to use the namespace when you try to find the ShipmentReceiptLineItem element. You also need to go from the root element, otherwise your check for Element(...) would only be able to find the root element:
XDocument xdoc = XDocument.Load("FirstPart.xml");
XNamespace tns = "urn:rosettanet:specification:interchange:ShipmentReceiptNotification:xsd:schema:02.01";
xdoc.Root.Add(XDocument.Load("RepeatingPart.xml")
.Root
.Element(tns + "ShipmentReceiptLineItem")
.Elements());
Or splitting it up further:
XDocument repeatingDoc = XDocument.Load("RepeatingPart.xml");
XNamespace tns = "urn:rosettanet:specification:interchange:ShipmentReceiptNotification:xsd:schema:02.01";
var elementsToAdd = repeatingDoc.Root
.Element(tns + "ShipmentReceiptLineItem")
.Elements());
var mainDoc = XDocument.Load("FirstPart.xml");
mainDoc.Root.Add(elementsToAdd);
I find this a lot simpler to read than doing everything in one go. You could potentially get rid of the repeatingDoc variable and do that bit inline, but I definitely wouldn't do the whole thing inline.

Returning Data from XML file with Multiple NameSpaces C#

I am having trouble returning data from a Linq to XML query.
I have the following XML
<sdnList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/sdnList.xsd">
<publshInformation>
<Publish_Date>03/14/2013</Publish_Date>
<Record_Count>5440</Record_Count>
</publshInformation>
</sdnList>
I am trying to get the value of Publish Date using the following
XDocument xDoc = XDocument.Load(fileName);
XNamespace xNS = "http://tempuri.org/sdnList.xsd";
XNamespace xNS1 = "http://www.w3.org/2001/XMLSchema-instance";
string strCurrentDate = xDoc.Element(xNS1 + sdnList").Element("publshInformation").Element("Publish_Date").Value;
This just returns an object expected error.
I know my problem is around the namespaces (and most likely is will be a simple solutions)
Thanks
All the elements in that document are in the http://tempuri.org/sdnList.xsd namespace, so you need something like
xDoc.Element(xNS + "sdnList")
.Element(xNS + "publshInformation")
.Element(xNS + "Publish_Date").Value;
This will work:
XNamespace xNS = "http://tempuri.org/sdnList.xsd";
string strCurrentDate = xDoc.Element(xNS + "publshInformation").Element(xNS + "Publish_Date").Value;

Remove specific nodes under the XML root?

My XML is below;
<XML ID="Microsoft Search Thesaurus">
<thesaurus xmlns="x-schema:tsSchema.xml">
<diacritics_sensitive>1</diacritics_sensitive>
<expansion>
<sub>Internet Explorer</sub>
<sub>IE</sub>
<sub>IE5</sub>
</expansion>
<expansion>
<sub>run</sub>
<sub>jog</sub>
</expansion>
</thesaurus>
</XML>
I want to remove the "expansion" nodes from the XML. After removing process, it would be like that;
<XML ID="Microsoft Search Thesaurus">
<thesaurus xmlns="x-schema:tsSchema.xml">
</thesaurus>
</XML>
My code is below;
XDocument tseng = XDocument.Load("C:\\tseng.xml");
XElement root = tseng.Element("XML").Element("thesaurus");
root.Remove();
tseng.Save("C:\\tseng.xml");
I got an error "Object reference not set to an instance of an object." for line "root.Remove()".
How can I remove the "expansion" nodes from XML file? Thanks.
Use:
Will remove only expansion elements:
XNamespace ns = "x-schema:tsSchema.xml";
tseng.Root.Element(ns + "thesaurus")
.Elements(ns + "expansion").Remove();
Will remove all children of thesaurus:
XNamespace ns = "x-schema:tsSchema.xml";
tseng.Root.Element(ns + "thesaurus").Elements().Remove();
Something like
XElement root = tseng.Element("XML").Element("thesaurus");
tseng.Element("XML").Remove(thesaurus);
You remove a node from it's parent...
if you want to remove just the expansion nodes, then basically you find a remove until tere aren't any in thesaurus, or return a list of them and loop through removing them from their parent thesaurus.
You have no success because your thesaurus have different namespace. You need to specify ti to get it works.
XNamespace ns = "x-schema:tsSchema.xml";
XDocument tseng = XDocument.Parse(xml);
XElement root = tseng.Element("XML").Element(ns + "thesaurus");
root.Elements().Remove();
In general your code valid. The only thing that you need to delete child elements not root to reach results you needed.

how to read value from XML?

The data:
<sys>
<id>SCPUCLK</id>
<label>CPU Clock</label>
<value>2930</value>
</sys>
<sys>
<id>CPUTEMP</id>
<label>CPU Temp</label>
<value>39</value>
</sys>
This is the code that I'm using to read the data:
XmlDocument document = new XmlDocument();
document.LoadXml(data);
XmlElement node = document.SelectSingleNode("/sys/value") as XmlElement;
Console.WriteLine("node = " + node);
The issue: Console.WriteLine("node = " + node); doesn't give me any output besides node: but no actual value like 2930 from the sample above.
Thanks
use node.value ie., XmlElement.value
As an alternative to using XmlDocument, you can also use LINQ to XML (which is my preference):
using System.Xml.Linq;
XDocument xDoc = new XDocument();
// Parse loads the XDocument with XML from a string
xDoc = XDocument.Parse(data);
string node = (from x in xDoc.Root.Elements("value")
select x.Value).SingleOrDefault();
Console.WriteLine("node = " + node);
Nothing wrong with using XmlDocument, especially for what you're doing, but you might want to check out LINQ to XML when you get a chance, as I find it a lot easier to work with than XmlDocument.
If you want to get all the "value" elements, simply remove the SingleOrDefault() from the query, and then you can loop through the result, like this:
var nodes = from x in xDoc.Root.Elements("value")
select x.Value;
foreach (var node in nodes)
{
Console.WriteLine("node = " + node);
}
Here's a site worth checking out:
LINQ to XML - 5 Minute Overview

C# Xml Value always getting null

I have the following Xml in my Resources.xmltest:
<?xml version="1.0" encoding="utf-8" ?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://DFISofft.com/SmartPayments/">
<Result>0</Result>
<Message>Pending</Message>
<PNRef>222131</PNRef>
<ExtData>InvNum=123</ExtData>
</Response>
I've tried several ways to get the values, Result,Message,PNRef,ExtData, out of it and I've had no luck. I always get a null value for the NodePath so it never goes into the loop:
var XmlDoc = new XmlDocument();
XmlDoc.LoadXml(Resources.xmltest);
XmlElement NodePath = (XmlElement) XmlDoc.SelectSingleNode("/Response");
while (NodePath != null)
{
foreach (XmlNode Xml_Node in NodePath)
{
Console.WriteLine(Xml_Node.Name + " " + Xml_Node.InnerText);
}
}
I've tried this:
XmlNode node3 = XmlDoc.SelectSingleNode("PNRef");
Console.WriteLine(node3.Value);
Console.WriteLine(XmlDoc.InnerXml);
var tst = XmlDoc.GetElementsByTagName("PNRef");
Console.WriteLine(tst);
And this:
NodePath = (XmlElement) XmlDoc.SelectSingleNode("/Response");
if (NodePath != null)
{
foreach (XmlNode node in NodePath)
{
Console.WriteLine("NodeName: " + Xml_NodeX.Name);
Console.WriteLine("NodeValue: " + node.InnerText);
}
}
Apparently, I'm not getting the xml read/write. I've done it with DataSets but they do all the work for you.
Can someone point me in the right direction? I've been at this for longer than I should have been already.
Thank you!
Your XML has a XML namespace and you're not paying any attention to it:
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://DFISofft.com/SmartPayments/">
******************************************
When selecting from this XML, you need to use that XML namespace!
You're not taking into account the XML namespace (xmlns="http://nts-de-osm1-pxc/webservices/") on the document!
Try this:
var XmlDoc = new XmlDocument();
// setup the XML namespace manager
XmlNamespaceManager mgr = new XmlNamespaceManager(XmlDoc.NameTable);
// add the relevant namespaces to the XML namespace manager
mgr.AddNamespace("ns", "http://DFISofft.com/SmartPayments/");
XmlDoc.LoadXml(Resources.xmltest);
// **USE** the XML anemspace in your XPath !!
XmlElement NodePath = (XmlElement) XmlDoc.SelectSingleNode("/ns:Response");
while (NodePath != null)
{
foreach (XmlNode Xml_Node in NodePath)
{
Console.WriteLine(Xml_Node.Name + " " + Xml_Node.InnerText);
}
}
The problem is your XPath query, which doesn't specify a namespace - despite the fact that your document only has a Response element in the "http://DFISofft.com/SmartPayments/" namespace. Ditto the PNRef elements.
Personally I'd use LINQ to XML if I actually wanted to use namespaces if at all possible. For example:
XNamespace ns = "http://DFISofft.com/SmartPayments/";
XDocument doc = XDocument.Load(filename);
foreach (var element in doc.Descendants(ns + "PNRef"))
{
// Use element here
}
As you can see, LINQ to XML makes it really easy to use namespaces - but of course it requires .NET 3.5 or higher. If I had to use .NET 2.0, I'd either use XmlNamespaceManager or iterate manually and check local names instead of using XPath.
That is because the node isn't called response; you need to take the namespace into account:
var XmlDoc = new XmlDocument();
var nsmgr = new XmlNamespaceManager(XmlDoc.NameTable);
nsmgr.AddNamespace("x", "http://DFISofft.com/SmartPayments/");
XmlDoc.LoadXml(yourXml);
XmlElement NodePath = (XmlElement)XmlDoc.SelectSingleNode("/x:Response", nsmgr);
For future reference...
Bubba Soft
This site has a great free tool for building XPath Expressions (XPath Builder).
It's because you are using the overload of SelectSingleNode that assumes an empty namespace. Since you have a default namespace you will need to use the version that takes an XmlNamespaceManager. See this article for more info.
from the docs:
If the XPath expression does not include a prefix, it is assumed that the namespace URI is the empty namespace. If your XML includes a default namespace, you must still add a prefix and namespace URI to the XmlNamespaceManager; otherwise, you will not get a node selected. For more information, see Select Nodes Using XPath Navigation.

Categories

Resources