Using Xpath to select single node, when node contains namespace - c#

I have following response for one of my SOAP request.
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<UploadIsoResponse xmlns="http://localhost:8000/gw/">
<UploadIsoResult>false</UploadIsoResult>
<status>ISO File does not exist</status>
<md5>string</md5>
<days>9/18/2015 12:00:00 AM</days>
</UploadIsoResponse>
</soap:Body>
</soap:Envelope>
And I am using following code to parse it. However I am getting an error Object reference not set to an instance of an object. This is actually because of the resulting null value returned from the xpath. Please help me on parsing single node.
public void fill_response_data(string xml_buffer)
{
string TARGET_NAME_SPACE = "http://localhost:8000/gw/";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml_buffer);
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);
ns.AddNamespace("msbld", TARGET_NAME_SPACE);
XmlNode md5_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/md5", ns);
XmlNode md5_status_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/status", ns);
txt_md5_checksum.Text = md5_node.InnerText;
txt_status.Text = md5_status_node.InnerText;
}
Exception : System.Xml.XmlDocumentAn unhandled exception of type 'System.NullReferenceException' occurred in IsoGateway.exe

Fixed the issue by adding name space in xpath and below is the updated snippet.
XmlNode md5_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/msbld:md5", ns);
XmlNode md5_status_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/msbld:status", ns);

Related

XML SelectSingleNode Namespacing issue

I'm trying to get a single value from an XML using the SelectSingleNode, but it keeps returning null on me.
I've been looking here on SO and it seems it has something to do with the namespace. I tried adding it but I keep getting null.
The XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<EML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xnl="urn:oasis:names:tc:ciq:xnl:4"
xmlns:xal="urn:oasis:names:tc:ciq:xal:4"
xmlns="urn:oasis:names:tc:evs:schema:eml"
xmlns:martine="http://www.martine.be/extensions"
Id="510"
SchemaVersion="7.0"
xsi:schemaLocation="urn:oasis:names:tc:evs:schema:eml schema/510-count-v7-0.xsd
http://www.martine.be/extensions schema/martine-eml-extensions.xsd">
<EMLHeader>
<TransactionId>01</TransactionId>
<ManagingAuthority>
<AuthorityIdentifier>2</AuthorityIdentifier>
<AuthorityName>
<NameElement ElementType="">VLR</NameElement>
</AuthorityName>
<Description>Some Description</Description>
<OrganizationURL>Unknown</OrganizationURL>
<AuthorityAddress/>
</ManagingAuthority>
</EMLHeader>
I'm trying to extract the Description using the code below:
XmlDocument doc = new XmlDocument();
doc.LoadXml(content);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "urn:oasis:names:tc:evs:schema:eml");
XmlNode testNode = doc.SelectSingleNode("/ns:EML/ns:EMLHeader/ns:ManagingAuthority/ns:Description", nsmgr);
if (testNode != null)
{
Console.WriteLine(testNode.InnerText);
}
What am doing wrong?
Tested this and you are missing closing </EML> tag. This was the error I got
Unhandled Exception: System.Xml.XmlException: Unexpected end of file has occurred. The following elements are not closed: EML. Line 24, position 17.
TestCodeApp.cs
using System;
using System.Xml;
public class Program
{
public static void Main()
{
XmlDocument doc = new XmlDocument();
doc.Load("input.xml");
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "urn:oasis:names:tc:evs:schema:eml");
XmlNode testNode = doc.SelectSingleNode("/ns:EML/ns:EMLHeader/ns:ManagingAuthority/ns:Description", nsmgr);
if (testNode != null)
{
Console.WriteLine(testNode.InnerText);
}
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<EML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xnl="urn:oasis:names:tc:ciq:xnl:4"
xmlns:xal="urn:oasis:names:tc:ciq:xal:4"
xmlns="urn:oasis:names:tc:evs:schema:eml"
xmlns:martine="http://www.martine.be/extensions"
Id="510"
SchemaVersion="7.0"
xsi:schemaLocation="urn:oasis:names:tc:evs:schema:eml schema/510-count-v7-0.xsd
http://www.martine.be/extensions schema/martine-eml-extensions.xsd">
<EMLHeader>
<TransactionId>01</TransactionId>
<ManagingAuthority>
<AuthorityIdentifier>2</AuthorityIdentifier>
<AuthorityName>
<NameElement ElementType="">VLR</NameElement>
</AuthorityName>
<Description>Some Description</Description>
<OrganizationURL>Unknown</OrganizationURL>
<AuthorityAddress/>
</ManagingAuthority>
</EMLHeader>
</EML>
Your code look OK, except:
you missed close node in the xml file: ""
if your content is contain information of above xml, then you can use doc.LoadXML(content), otherwise you should use doc.Load(fileName).
Your xml file should be:
<?xml version="1.0" encoding="UTF-8"?>
<EML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xnl="urn:oasis:names:tc:ciq:xnl:4"
xmlns:xal="urn:oasis:names:tc:ciq:xal:4"
xmlns="urn:oasis:names:tc:evs:schema:eml"
xmlns:martine="http://www.martine.be/extensions"
Id="510"
SchemaVersion="7.0"
xsi:schemaLocation="urn:oasis:names:tc:evs:schema:eml schema/510-count-v7-0.xsd
http://www.martine.be/extensions schema/martine-eml-extensions.xsd">
<EMLHeader>
<TransactionId>01</TransactionId>
<ManagingAuthority>
<AuthorityIdentifier>2</AuthorityIdentifier>
<AuthorityName>
<NameElement ElementType="">VLR</NameElement>
</AuthorityName>
<Description>Some Description</Description>
<OrganizationURL>Unknown</OrganizationURL>
<AuthorityAddress/>
</ManagingAuthority>
</EMLHeader>
</EML>
And then you can read it:
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "urn:oasis:names:tc:evs:schema:eml");
XmlNode testNode = doc.SelectSingleNode("/ns:EML/ns:EMLHeader/ns:ManagingAuthority/ns:Description", nsmgr);
if (testNode != null)
{
Console.WriteLine(testNode.InnerText);
}

Issue on saving the XML file after editing it

I have an XML file with some data on it..for example
<?xml version="1.0" encoding="utf-8"?>
<CreateAndSendMessageRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.communisis.com/lv">
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
Now i want to replace POLICY REFERENCE value with some dummy data. I am able to do that but now i have to save it as a new file with a different file name..
How can i achieve that..
For reference i am giving my code.
XmlDocument doc = new XmlDocument();
doc.Load(filepath);
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
var item =node.Item(0);
string value = item.FirstChild.Value;
string nevalue = value.Replace(value, "Test123");
doc.DocumentElement.;
doc.Save(#"C:\Test\file.xml");
The xml wasn't valid.
Anyway, this is how to make it work:
Xml file:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Code:
XmlDocument doc = new XmlDocument();
doc.Load("bho.xml");
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
node[0].InnerText = "Test123";
doc.Save("file.xml");
Result xml:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>Test123</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Hope it helps you ^^

How to working with xml nodes

I have program with response from website in the xml format with namespace.
example program:
string responsedata;//response data from website
//Creat new XMLdoc object for response data
XmlDocument ResponseDataXml = new XmlDocument();
ResponseDataXml.InnerXml= responsedata;
XmlNamespaceManager xnsm = new XmlNamespaceManager(ResponseDataXml.NameTable);
xnsm.AddNamespace("ps","http://example.com/namespace/ps");
//create xml document fro validating DTD
XmlDocument ValidateXml = new XmlDocument();
//select Nodes <ps:results> ... <result>
XmlNodeList NodesResults = ResponseDataXml.SelectNodes("ps:results/result");
foreach (XmlNode node in NodesResults)
{
ValidateXml.InnerText= "";
ValidateXml.InnerText += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
ValidateXml.InnerText += "<!DOCTYPE SouborN1A SYSTEM \"validate_dtd.dtd\">";
ValidateXml.InnerText+=node.InnerXml;
ValidateXml.Save("validate_temp.xml");
if (validate("validate_temp.xml"))//validate() return true if document is valid
{
Console.WriteLine("Result:" + node.Attributes["id"] + " is valid !!!!!");
// here i can append "result" node in new xml document "Valid_result.xml"
}
else
{
Console.WriteLine("Result:"+ node.Attributes["id"] + "i invalid !!!!!");
// here i can append "result" in new xml document invalid result in to "invalid_result.xml"
}
}
Input postdata:
<ps:report xmlns:ps="example.com.....">
<results xmlns:ps="example.com....." ps:Identifikation="999999">
<result id="11125">
.......
</result>
<result id="1100">
.......
</result>
<result id="111999055">
.......
</result>
<result id="100000">
.......
</result>
</results>
</ps:report>
Please help me... :)
I do not know how to proceed, and work with a given output,
I need mainly validate the item separately and then store in a xml file.
I apologize for my English.
Thanks.
Unfortunately, this question is fairly broad, but generally speaking everything can be done with XML libraries in C#. For example, use the XmlDocument class to create elements and then simply append those elements to the existing nodes.
class Program
{
static void Main(string[] args)
{
var output = new XmlDocument();
output.AppendChild(output.CreateXmlDeclaration("1.0", "utf-8", null));
var xmlns = new XmlNamespaceManager(output.NameTable);
var root = output.CreateElement("ps", "report", "http://example.com/namespace/ps");
var list = output.CreateElement("ps", "results", "http://example.com/namespace/ps");
list.Attributes.Append(output.CreateAttribute("Identifikation"));
list.Attributes[0].Value = "999999";
root.AppendChild(list);
var item = output.CreateElement("ps", "result", "http://example.com/namespace/ps");
item.Attributes.Append(output.CreateAttribute("id"));
item.Attributes[0].Value = "11125";
list.AppendChild(item);
//TODO: Append more validation messages.
output.AppendChild(root);
output.WriteTo(new XmlTextWriter(Console.Out));
System.Console.ReadLine();
}
}
Produces a document like this:
<?xml version="1.0" encoding="utf-8"?>
<ps:report xmlns:ps="http://example.com/namespace/ps">
<ps:results Identifikation="999999">
<ps:result id="11125" />
</ps:results>
</ps:report>

XMLNodeList not populating

This is my XML,It is actually an InfoPath form with a word doc attachment in the Attachment node - but I have removed the code for better readablity.
<?xml version="1.0" encoding="UTF-8"?><?mso-infoPathSolution solutionVersion="1.0.0.527" productVersion="14.0.0" PIVersion="1.0.0.0" href="http://intranet/workspace/departments/IT/fakehomepage/Testing/Forms/template.xsn" name="urn:schemas-microsoft-com:office:infopath:Testing:-myXSD-2011-11-22T09-08-23" ?><?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.3"?><?mso-infoPath-file-attachment-present?><my:Template xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapEnc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:tns="http://www.sourcecode.co.za/webservices/RuntimeServices" xmlns:d="http://schemas.microsoft.com/office/infopath/2003/ado/dataFields" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:ns1="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2011-11-22T09:08:23" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-za">
<my:scn1>
<my:Attachment>the raw source-removed for space saving</my:Attachment>
<my:DataValue>Hello-2013-07-04T09:05:50</my:DataValue>
</my:scn1>
<my:scn2></my:scn2>
<my:scn3></my:scn3>
<my:scn4></my:scn4>
<my:scnSubmit></my:scnSubmit>
<my:scnHideMe></my:scnHideMe>
</my:Template>
This is my attempt so far
XmlDocument myDoc = new XmlDocument(); //works
myDoc.Load(#"Form.xml"); //works
XmlNodeList nl = myDoc.SelectNodes("//Attachment"); //Doesn't work, nodecount still zero.
foreach (XmlNode n in nl)//skips because no nodes loaded.
I have also tried
XmlNodeList nl = myDoc.SelectNodes("//my:scn1");
I need to get the raw source out of there so i can decode and save the word document.
enter code here
To get the namespace working, you need to use XmlNamespaceManager.
XmlDocument myDoc = new XmlDocument();
myDoc.Load(#"Form.xml");
XmlNamespaceManager xmlNsMgr = new XmlNamespaceManager(myDoc.NameTable);
xmlNsMgr.AddNamespace("my", myDoc.DocumentElement.NamespaceURI);
XmlNodeList nl = myDoc.SelectNodes("//my:Attachment", xmlNsMgr);
With this, nl will be populated.

How read value from XmlNode

I have a Xml file and I try to read value from node Ticket, but my output is still empty. Can somebody help me ?
Xml docmunet :
<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:Header>
<TicketHeader xmlns="http://tempuri.org/">
<Ticket>
heslo
</Ticket>
</TicketHeader>
</soap:Header>
<soap:Body>
<test xmlns="http://tempuri.org/"/>
</soap:Body>
</soap:Envelope>
My code :
doc= new XmlDocument();
doc.Load(path);
XmlNode temp = doc.SelectSingleNode("//Ticket");
textBox3.Text=temp.InnerXml;
I think you are using the wrong path to the node you want and use '.InnerText'. Here is the corrected code:
doc= new XmlDocument();
doc.Load(path);
string ticket = doc.SelectSingleNode("//TicketHeader/Ticket").InnerText;
this will be the correct for your requirement
doc= new XmlDocument();
doc.Load(path);
XmlNode temp = doc.SelectSingleNode("//TicketHeader/Ticket");
textBox3.Text=temp.InnerXml;
thanks,
KRG

Categories