SelectNodes Always returning the 0 count - c#

SelectNodes always returning the 0 count even the it has the value.
<?xml version="1.0" encoding="utf-16"?>
<Configurations xmlns="DEH_Common.Schemas">
<sftpConfiguration>
<file>
<filedetails>
<fileext>csv</fileext>
<DataContentDetailId>1</DataContentDetailId>
</filedetails>
</file>
</sftpConfiguration>
</Configurations>
C# to read the nodelist....
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("//Configurations/sftpConfiguration/file");

It's because of using namespace in your xml, You should add namespace to xmlDoc and also no need to useDocumentElement` This code would be work:
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("a", "DEH_Common.Schemas");
XmlNodeList nodeList = xmlDoc.SelectNodes("//a:sftpConfiguration/a:file", nsmgr);

In your XML DocumentElement is the Configurations node, so your XPath should be sftpConfiguration/file
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("sftpConfiguration/file");

Try this:
xmlDoc.DocumentElement.SelectNodes("/Configurations[#*]/sftpConfiguration/file");

Related

How can I parse the following xml in c#

I need some help on how to get values of English and studentId from this XML. Maybe it needs some special parsing I can't figure out at the moment.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<processResponse xmlns="http://tempuri.org/">
<processResult>
<xml version="1.0" encoding="UTF-8"?>
<returnedResponse>
<English>94</English>
<Remarks>Excellent</Remarks>
<studentId>tst005</studentId>
<Department>6</Department>
</returnedResponse>
</processResult>
</processResponse>
</soap:Body>
</soap:Envelope>
I have tried the following code:
XmlDocument xdr = new XmlDocument();
xdr.LoadXml(thexml);
XmlNodeList nodelist = xdr.SelectNodes("//processResponse/processResult/returnedResponse");
foreach (XmlNode node in nodelist)
{
string eng = node.SelectSingleNode("English").InnerText;
Response.Write("eng");
}
Do you get an error with invalid XML or does your SelectNodes not find anything?
How about this path
XmlNodeList nodelist = xdr.SelectNodes("/*/*/*/processResponse/processResult/returnedResponse");
You can try with SelectSingleNode, just like this.
var English= xdr.DocumentElement.SelectSingleNode("English").InnerText;
var studentId = xdr.DocumentElement.SelectSingleNode("studentId").InnerText;
1) XML ist invalid at line 6 -> because it does not have a closing tag. If you cannot edit the Service and strip the xml header or encode the resulting xml, you have to strip the line 6 in you consumercode.
2) You have to define the Namespaces!
Btw: I highly recommend using (Linq2XML) XDocument. Your code could look like this:
XDocument xdr = XDocument.Parse(...);
var nodes = xdr.XPathSelectElements("//*[name()='returnedResponse']");
Try this
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
XmlNodeList nList = doc.GetElementsByTagName("returnedResponse");
foreach (XmlNode node in nList)
{
XElement xelement = XElement.Parse(node.OuterXml);
var Descendents = xelement.Descendants();
foreach (var item in Descendents)
{
//you'll get each of your descendents here
}
}

Using underscore and period with XPath

I need to select a node which has attribute name as _1.1.1
I am trying to select the node as
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("IKS", "http://schemas.microsoft.com/wix/2006/objects");
XmlNode xRootNode = xmlDoc.SelectSingleNode("//folder[#name='Global']");
But it doesn't return any. I'm sure its because of the special characters in my expression. How should I handle it to get the desired node?
EDIT: I access node as
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("IKS", "http://schemas.microsoft.com/wix/2006/objects");
XmlNode xRootNode = xmlDoc.SelectSingleNode("//folder[#name='Global']", nsmgr);
and the XML is
<?xml version="1.0" encoding="UTF-8"?>
<workplace xmlns='IKS:'>
<cabinet name='Groups%20and%20Departments' oid='_1.25.18'>
<folder name='Global' oid='_1.11.9882'></folder>
</cabinet>
</workplace>
You're very close to having the correct approach. You have declared a namespace prefix, but you need to actually use it:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("IKS", "http://schemas.microsoft.com/wix/2006/objects");
XmlNode xRootNode = xmlDoc.SelectSingleNode("//IKS:folder[#name='Global']");
// ^^^^------- here
Note: For some reason, you have xmlns="IKS:" in your XML. If that is in fact what your XML looks like, then IKS: is the namespace URI you need to use:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("IKS", "IKS:");
XmlNode xRootNode = xmlDoc.SelectSingleNode("//IKS:folder[#name='Global']");

How to get element value using c#

XML file:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<content>
<FingerPrintUserDetails>
<UserID>e57645</UserID>
<UserName>Jill</UserName>
<FPData>AQAAABQAAAD0AAAAAQASAAEAWgAAAAAA8AAAAHfrWpB6BHZBL10voxpdxu2Km5XVNh*oUNC80Rvpql3RhlqOiBPeet6iRPwb/BdN1fCF4Y/WHbQ40*mqoUKqilgN7bUqNuXP7M299HUWtoAGEO3nDKXXAnHd7dgytZbmHVv*mRBPJDSRw9VY/R1yOIu2cCDlLM*F8Q1lvTfMFDdfwNZynI0e2ZauCF58f0UX56XLFBallaAauxP5mvvhUmcmc6ITg7RhH9wc4181kgPjCuZg38pQepE5U07XIa3hQP8fwxPzdprifXECgB1Z3pTXWQP0q4ZD0Inlbq6Gszo1ucPrhQA0jYQRXtJUVuyBeg</FPData>
<Address>Pune</Address>
<ContactNo>848488484884</ContactNo>
</FingerPrintUserDetails>
<FingerPrintUserDetails>
<UserID>444</UserID>
<UserName>John</UserName>
<FPData>AQAAABQAAADkAAAAAQASAAEAZAAAAAAA4AAAAPLnmQ8FymAAHWYutR5pdtYvfDVmjsqLeli8tOSTFAtw6AkfA0r8XwrMzp9jFZJI7DlBk4G94BMq55gPEG7uBLZUNYrvhv0jDlDFMOjWGJ9RoWekFveTC*oZ7Tq/xmxuvY6FzLHVo*xzdKQI73Y0f9/eeMC0OgqnbQ3I0IP6cTkkKnTUZJOXKr7IFPHkjJAvCDmU7ec4vG50JHdBJIObmbzVcO0huTUQyE7CR1qYkUjmNFKgVKWPLRupEk4l/Ek0BuAba*9JlhBVUHzZuKbDQLc9lTFwevAgDuuAwxfZaLS*</FPData>
<Address>nagpur</Address>
<ContactNo>464645763</ContactNo>
</FingerPrintUserDetails>
<FingerPrintUserDetails>
<UserID>5555</UserID>
<UserName>Jack</UserName>
<FPData>AQAAABQAAAAEAQAAAQASAAEAZAAAAAAA9AAAAPz5mQO3uTeXLfU5Mb74XbCX5rERGZFPQMVG1vPpX87306O5oURlYiIe5dasJ2S8NlBZu2UU3zaUpNnB7viYDB6*wfFlgtopn/WdbXW0Yhik3hj8nDreEmaK12To8qfAJx2ooq43i0wBIL*0Jkba*QpHIprSajrhnCg1PjOLMP37sEauJUwXJaoDR/PPQYIxTFE5kf8xzGlJmqiGejD*Y8R3ewU9yIrxkdQ0S//LCdacULt2QvS/I3APo/j0FAgSCOU3SBLdDL6UBPD4fLeEzo7uUIW8gUMThzZX*u2iUuNwJdqWC2NsFtWkUWt03sz3xYQpR8pLA4vrsUmldzUMWe8</FPData>
<Address>beed</Address>
<ContactNo>5745745747</ContactNo>
</FingerPrintUserDetails>
</content>
C#:
XmlDocument doc = new XmlDocument();
doc.Load("E://BioEnable_Project//fp_project_using_xml//fp_project_using_xml//Capture_Data.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("FPData");
foreach(XmlElement node in nodes)
{
MessageBox.Show(node.Value);
}
I have to check FPData value on each node..i use above code but not getting..
In your XPath, provide the full path to the node.
XmlNodeList nodes = root.SelectNodes("/content/FingerPrintUserDetails/FPData");
What is happening is that there is no direct FPData node under the document root.
XmlNodeList nodes = root.SelectNodes("content/FingerPrintUserDetails");
it will return array of FingerPrintUserDetails, then find FPData in them
XmlNodeList res = nodes[index].SelectNodes("FPData");
Using LINQ to XML:
XDocument doc = XDocument.Load("XmlFilePath");
var selectors = from elements in doc.Elements("content").Elements("FingerPrintUserDetails")
select elements;
foreach (var element in selectors)
{
MessageBox.Show(element.Element("FPData").Value);
}
XmlDocument doc = new XmlDocument();
doc.Load("E://BioEnable_Project//fp_project_using_xml//fp_project_using_xml//Capture_Data.xml");
XmlNodeList lst = doc.GetElementsByTagName("FingerPrintUserDetails");
foreach (XmlElement elem in lst)
{
XmlNode pfData = doc.GetElementsByTagName("FPData")[0];
MessageBox.Show(pfData.Value);
}

Reading Elements within a Namespace

I have an XML file that looks like:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://www.someurl.com/somefile.xslt"?>
<AutoInsuranceClaim xmlns="http://www.someurl.com/schemas/AutoInsuranceClaim">
<Identification>
<BaseOwner>3</BaseOwner>
<BaseType>ABC123</BaseType>
<BaseTypeRef>471038341757</BaseTypeRef>
</Identification>
</AutoInsuranceClaim>
and I'm trying to read the Identification node. Here's my code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"..\..\Data.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", "http://www.someurl.com/schemas/AutoInsuranceClaim");
XmlNodeList nodeList = xmlDoc.SelectNodes(#"/ns:AutoInsuranceClaim/Identification", nsmgr);
Console.WriteLine("There are {0} nodes...", nodeList.Count);
I know I should get a least 1 value. My understanding of .NET XML parsing is that if you have a default namespace with no prefix, you have to create your own namespace. But this should have returned 1.
If not, what am I missing?
I might be grasping at straws here, but shouldn't you be namespacing both entities in your xpath expression?
XmlNodeList nodeList = xmlDoc.SelectNodes(#"/ns:AutoInsuranceClaim/ns:Identification", nsmgr);
XElement root = XElement.Load("Data.xml");
var identifications = root.Descendants()
.Where(x => x.Name.LocalName == "Identification")
.ToList()
The problem is that you're trying to find an Identification node without a namespace, but it will have defaulted to the same namespace as the parent due to the xmlns=... part. Try this:
var nodeList = xmlDoc.SelectNodes("/ns:AutoInsuranceClaim/ns:Identification",
nsmgr);
Having tried it myself, it printed a count of 1.
Personally I'd use LINQ to XML instead though, which makes namespace easier handling:
XDocument doc = XDocument.Load(#"..\..\Data.xml");
XNamespace ns = "http://www.someurl.com/schemas/AutoInsuranceClaim";
var nodes = doc.Root.Elements(ns + "Identification");

how we can set value for xml element using XmlDocument class

Is it possible to set value dynamically for any XML element using the XmlDocument class? Suppose my XML is
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<soapenv:Body>
<v9:ProcessShipmentReply xmlns:v9="http://fedex.com/ws/ship/v9">
<v9:HighestSeverity xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SUCCESS</v9:HighestSeverity>
<v9:Notifications xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v9:Severity>SUCCESS</v9:Severity>
<v9:Source>ship</v9:Source>
<v9:Code>0000</v9:Code>
<v9:Message>Success</v9:Message>
<v9:LocalizedMessage>Success</v9:LocalizedMessage>
</v9:Notifications>
<v9:CompletedShipmentDetail>
<v9:CompletedPackageDetails xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v9:SequenceNumber>1</v9:SequenceNumber>
<v9:TrackingIds>
<v9:TrackingIdType>GROUND</v9:TrackingIdType>
<v9:TrackingNumber>634649515000016</v9:TrackingNumber>
</v9:TrackingIds>
<v9:Barcodes>
<v9:BinaryBarcodes>
<v9:Type>COMMON_2D</v9:Type>
<v9:Value>Wyk+HjAxHTAyMDI3ODAdODQwHTEzNx02MzQ2NDk1</v9:Value>
</v9:BinaryBarcodes>
<v9:StringBarcodes>
<v9:Type>GROUND</v9:Type>
<v9:Value>9612137634649515000016</v9:Value>
</v9:StringBarcodes>
</v9:Barcodes>
<v9:Label>
<v9:Type>OUTBOUND_LABEL</v9:Type>
<v9:ShippingDocumentDisposition>RETURNED</v9:ShippingDocumentDisposition>
<v9:Resolution>200</v9:Resolution>
<v9:CopiesToPrint>1</v9:CopiesToPrint>
<v9:Parts>
<v9:DocumentPartSequenceNumber>1</v9:DocumentPartSequenceNumber>
<v9:Image>iVBORw0KGgoAAAANSUhEUgAAAyAAAASwAQAAAAAryhMIAAAagEl</v9:Image>
</v9:Parts>
</v9:Label>
</v9:CompletedPackageDetails>
</v9:CompletedShipmentDetail>
</v9:ProcessShipmentReply>
</soapenv:Body>
How could I set value for the below element like
<v9:Severity>SUCCESS</v9:Severity>
<v9:Source>ship</v9:Source>
I know how to extract data from XML and I think it is also possible to set value for the XML element using XMLDocument class. Looking for guidance.
If you know how to select a value, then you probably know how to update one too.
XmlDocument doc = new XmlDocument();
doc.Load(...);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("v9", "http://fedex.com/ws/ship/v9");
XmlNode severityNode = doc.SelectSingleNode("//v9:Severity", nsMgr);
severityNode.innerText = "FAILURE";
The important thing to know is that the <v9:Severity> node has an inner text() node, so in the example above you can't use the Node.Value property. To do that you would do something like this instead:
XmlNode severityTextNode = doc.SelectSingleNode("//v9:Severity/text()", nsMgr);
severityTextNode.Value = "FAILURE";
Note the subtle differences.
Do an XPath to the superior node using the XMLDocument class and add the 2 extra nodes on the tree.

Categories