Trying to change a XML node with no success - c#

I'm trying to change a the value for the model atribute from the following .xml file.
<MTConnectDevices xmlns="urn:mtconnect.org:MTConnectDevices:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mtconnect.org:MTConnectDevices:1.1 http://www.mtconnect.org/schemas/MTConnectDevices_1.1.xsd">
<Header version="1.1" sender="Company MTConnect Instance" creationTime="2010-08-26T19:00:47-07:00" instanceId="2" bufferSize="131072" />
<Devices>
<Device name="XX" iso841Class="1" uuid="000" id="id1001">
<Description manufacturer="name" serialNumber="Serial Number" model="UNDEFINED">
</Description>
This is what I've tried but it's not working as it's not changing the value for model.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(mypath);
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
var node = xmlDoc.SelectSingleNode("/ns:MTConnectDevices/ns:Header/ns:Devices/ns:Device/ns:Description", nsmgr);
node.Attributes["model"].Value = "changed";
xmlDoc.Save(mypath);
Can anyone give me a hand and tell me how to fix this?

Your xml contains namespaces, so you have to use them while retrieving node.
It can be done something like this:
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
var node = xmlDoc.SelectSingleNode("/ns:MTConnectDevices/ns:Devices/ns:Device/ns:Description", nsmgr);

Related

How to get 'xpath' value if the root node 2 xmlns url and one xmlns don't have prefix?

I have two xmlns attribute and I try to xpath one node but it is not working
I am using XmlDocument and I am trying to xpath from that xml . it returns null because the root node have two xml attributes.
<CreateRequest
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://fex.com/ws/openship/v15">
<WebAuthenticationDetail>
<Parent>
<Key/>
<Password />
</Parent>
<UserCredential>
<Key />
<Password />
</UserCredential>
</WebAuthenticationDetail>
<ClientDetail>
<AccountNumber />
<MeterNumber />
</ClientDetail>
</CreateRequest>
var nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var
nodes=xml.SelectNodes("/CreateRequest/ClientDetail/AccountNumber",nsmgr);
Your xml has a default namespace. You have to add it, assign it a prefix (I used ns). And then use this prefix in xpath.
Use it as follows:
var nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("ns", "http://fex.com/ws/openship/v15");
var nodes = xml.SelectNodes("/ns:CreateRequest/ns:ClientDetail/ns:AccountNumber", nsmgr);
you can ignore the namespaces.
xml.SelectNodes("/*[local-name()='CreateRequest']/*[local-name()='ClientDetail']/*[local-name()='AccountNumber']");

Xml path that have multiple namespaces

I can't figure out what namespaces need to be used for following Xml (sample):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ResponseCharge xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ResponseInfo xmlns="http://www.example.net">
<ResponseDetail>
<ResponseCode>00</ResponseCode>
<RequestIdentifier>1029034</RequestIdentifier>
<RetrievalReferenceNumber>634716660366</RetrievalReferenceNumber>
<ProcessingTime>00:03:314</ProcessingTime>
</ResponseDetail>
<ResponseTransactionDetail>
<AVSResponseCode />
<CVVResponseCode />
<AuthorizationSourceCode />
<AuthorizationNumber>004454</AuthorizationNumber>
</ResponseTransactionDetail>
<EMVResponseData />
</ResponseInfo>
</ResponseCharge>
</s:Body>
</s:Envelope>
My code looks like this atm:
XmlDocument doc = new XmlDocument();
doc.Load(responseXmlFile);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
//nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
//nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
//nsmgr.AddNamespace("", "http://www.example.net");
// getting NULL here
XmlNode node = doc.SelectSingleNode("/s:Envelope/s:Body/ResponseCharge/ResponseInfo/ResponseTransactionDetail/AuthorizationNumber", nsmgr);
I'm following this post: Namespace Manager or XsltContext needed
You need to include the namespace in your query for the elements in the http://www.example.net/ namespace.
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("ex", "http://www.example.net");
XmlNode node = doc.SelectSingleNode(
"/s:Envelope/s:Body/ResponseCharge/ex:ResponseInfo/ex:ResponseTransactionDetail/ex:AuthorizationNumber",
nsmgr);
I've arbitrarily picked ex as the prefix here. What's defined in the XmlNamespaceManager only relates to your XPath query, the prefixes used in the document aren't relevant.
Alternatively, I'd suggest you use LINQ to XML:
XNamespace ns = "http://www.example.net"
var doc = XDocument.Load(responseXmlFile);
var authNo = (int)doc.Descendants(ns + "AuthorizationNumber").Single();

Unable to Read XML using C# and XmlDocument

I would like to read a XML File with C#, but i always get an error.
This is my XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<OMDS xmlns="urn:omds20" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:omds20 ./omds26-00.xsd">
<PAKET VUNr="014" PaketZpktErstell="2014-08-29T10:45:08.575" PaketZpktLetztErstell="2014-08-29T10:45:08.575" PaketInhCd="VM" PaketUmfCd="G" VUVersion="26-00" DVRNrAbs="0">
<PERSON ....
<PERSON ....
<PERSON ....
I would like to read this XML, but XMLContentNodes is always null. So i am unable to get the SelectSingleNode with this Path, but i cant find out what should be wrong here?
XmlDocument doc = new XmlDocument();
doc.Load(openFileDialog1.FileName);
XmlNode XMLContentNodes = doc.SelectSingleNode("/OMDS/PAKET"); // Error Here
XmlNodeList PersonNodeList = XMLContentNodes.SelectNodes("PERSON");
foreach (XmlNode node in PersonNodeList)
{
.....
Any help would be greatly appreciated.
The usual namespace problem. Try
XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
mgr.AddNamespace("d", "urn:omds20");
XmlNode XMLContentNodes = doc.SelectSingleNode("/d:OMDS/d:PAKET", mgr);
XmlNodeList PersonNodeList = XMLContentNodes.SelectNodes("d:PERSON", mgr);
You'll need to add the namespace urn:omds20 to the doc XmlDocument object after loading your XML file in it. It will look like the following:
XmlDocument doc = new XmlDocument();
doc.Load(openFileDialog1.FileName);
XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(doc.NameTable);
xmlnsManager.AddNamespace("omds20", "urn:omds20");
Then you can query for the PAKET node like this:
XmlNode paketNode = doc.SelectSingleNode("/omds20:OMDS/omds20:PAKET", xmlnsManager);

XPath issue with SelectSingleNode?

I'm trying to get a node from an XML string in C# using SelectSingleNode. The XML string comes from an external source.
string logonXML = #"<attrs xmlns=""http://www.sap.com/rws/bip\"">
<attr name=""userName"" type=""string""></attr>
<attr name=""password"" type=""string""></attr>
<attr name=""auth"" type=""string"" possibilities=""secEnterprise,secLDAP,secWinAD,secSAPR3"">secEnterprise</attr>
</attrs>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(logonXML);
XmlNode root = doc.DocumentElement;
XmlNode usernameXML = root.SelectSingleNode("//attr[#name='userName']");
Debug.WriteLine(usernameXML.OuterXml);
However usernameXML is null. I've tried using both the doc and root with a couple variations of XPath queries, but can't seem to find the node. What is wrong with this XPath? Or am I using the library wrong?
You need to take into account the XML namespace that's defined on your root node!
Try something like this:
string logonXML = #"<attrs xmlns=""http://www.sap.com/rws/bip"">
<attr name=""userName"" type=""string""></attr>
<attr name=""password"" type=""string""></attr>
<attr name=""auth"" type=""string"" possibilities=""secEnterprise,secLDAP,secWinAD,secSAPR3"">secEnterprise</attr>
</attrs>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(logonXML);
// define the XML namespace(s) that's in play here
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "http://www.sap.com/rws/bip");
// select including the XML namespace manager
XmlNode usernameXML = doc.SelectSingleNode("/ns:attrs/ns:attr[#name='userName']", nsmgr);
string test = usernameXML.InnerText;

manipulation of xml using c#

If I want to add, update or delete node in the xml using c#, how can it be done? My xml is shown below. I dont want transactionID node. I want to add a node called <Transformation>XML</Transformation> after corelationID node.
<?xml version="1.0" ?>
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>HMRC-VAT-DEC</Class>
<Qualifier>poll</Qualifier>
<Function>submit</Function>
<TransactionID />
<CorrelationID>1B93D48C02D740C6B79DE68A27F3ADE5</CorrelationID>
<ResponseEndPoint PollInterval="10">https://secure.dev.gateway.gov.uk/poll</ResponseEndPoint>
<GatewayTimestamp>2011-04-05T07:41:43.018</GatewayTimestamp>
</MessageDetails>
<SenderDetails />
</Header>
<GovTalkDetails>
<Keys />
</GovTalkDetails>
<Body />
</GovTalkMessage>
The easiest thing to use would be LINQ to XML. For example:
XDocument doc = XDocument.Load("file.xml");
XNamespace ns = "http://www.govtalk.gov.uk/CM/envelope";
// Remove TransationID
XElement transactionElement = doc.Descendants(ns + "TransactionID").Single();
transactionElement.Remove();
// Add XML:
XElement correlationElement = doc.Descendants(ns + "CorrelectionID").Single();
XElement newElement = new XElement(ns + "XML");
correlationElement.AddAfterSelf(newElement);
// Save back
doc.Save("new-file.xml");
//Load the XML
XmlDocument documentXML = new XmlDocument();
documentXML.Load(Server.MapPath("AddDeleteUpdate.xml"));
XmlNamespaceManager xmlns = new XmlNamespaceManager(documentXML.NameTable);
xmlns.AddNamespace("bk", "http://www.govtalk.gov.uk/CM/envelope");
//Identify the parent node i.e <MessageDetails>
XmlNode nodeMessage = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails", xmlns);
//Delete the node.
XmlNode nodeTransactionID = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails/bk:TransactionID", xmlns);
nodeMessage.RemoveChild(nodeTransactionID);
//Create the new XML noded to be added.
XmlNode controlAttrNode = null;
controlAttrNode = documentXML.CreateElement("Transformation");
controlAttrNode.InnerText = "XML";
controlAttrNode.Attributes.RemoveAll();
//Get the node object to where it need to be added.
XmlNode nodeCorrelation = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails/bk:CorrelationID", xmlns);
//Insert the node after.
nodeMessage.InsertAfter(controlAttrNode, nodeCorrelation);
documentXML.Save(Server.MapPath("AddDeleteUpdate.xml"));
You'll need
XMLNode.InsertAfter(newChildNode,referenceChildNode)
This should kickstart you:
http://msdn.microsoft.com/en-US/library/system.xml.xmlnode.insertafter%28v=VS.80%29.aspx

Categories

Resources