how to replace xml elements with another xml elements in c#? - c#

This is my two xml document.
This xml is stored in paraouterXml string.
<w:tbl>
<w:tblPr>
</w:tblPr>
<w:tblGrid>
</w:tblGrid>
</w:tbl>
This xml is stored in tblMetaInfo string.
<root>
<w:tblPr>
<w:tblStyle w:val="TableGrid" />
<w:tblW w:w="0" w:type="auto" />
<w:tblLook w:val="04A0" />
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="1947" />
<w:gridCol w:w="1947" />
</w:tblGrid>
</root>
So,here i want to replace paraouterXml's <w:tblPr>,<w:tblGrid> with tblMetaInfo's <w:tblPr>,<w:tblGrid> elements.
This is c# code...
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(table.OuterXml);
XmlNode newNode = xDoc.DocumentElement;
XmlNodeList tblPrNode = xDoc.GetElementsByTagName("w:tblPr");
tblPrNode[0].RemoveAll();
XmlNodeList tblGridNode = xDoc.GetElementsByTagName("w:tblGrid");
tblGridNode[0].RemoveAll();
XmlDocument xDoc1 = new XmlDocument();
xDoc1.LoadXml(tblMetaInfo);
XmlNode newNode1 = xDoc1.DocumentElement;
XmlNodeList tblPrNode1 = xDoc1.GetElementsByTagName("w:tblPr");
XmlNodeList tblGridNode1 = xDoc1.GetElementsByTagName("w:tblGrid");
tblPrNode[0].ReplaceChild(tblPrNode1[0], tblPrNode[0]);
tblGridNode[0].ReplaceChild(tblGridNode1[0], tblGridNode[0]);
But it throwing some error...
Please guide me to get out of this issue...

ArgumentException: The newChild was created from a different document than the one that created this node.
public XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild):
If the newChild was created from another document, you can use XmlDocument.ImportNode to import the node to the current document. The imported node can then be passed to the ReplaceChild method.

Related

Extracting objects from xml that uses node prefixes using xpath

I have the following XML in a file called C:\temp\config.xml:
<?xml version="1.0" encoding="utf-8"?>
<dvp:systemConfig xmlns:devop="urn:foo.com:sys:rules">
<dvp:map id="rootFolderMap">
<dvp:entry key="anything" value="folder1"/>
<dvp:entry key="config" value="folder2"/>
<dvp:defaultValue value="folder1" />
</dvp:map>
<dvp:map id="folderMappings">
<dvp:entry key="SYS" value="System" />
<dvp:entry key="OPS" value="Operations" />
<dvp:entry key="DEV" value="Development" />
<dvp:defaultValue value="Miscellaneous" />
</dvp:map>
</dvp:systemConfig>
I am now trying to write C# code that will extract values from this XML. In particular, the list of value properties in the nodes.
List<string> folderNames = new List<string>
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\temp\config.xml");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
XmlNodeList xmlNodeList =
doc.SelectNodes("/systemConfig/map[#id='folderMappings']/entry",nsMgr);
foreach (XmlNode xmlNode in xmlNodeList)
{
// I'm hoping xmlNodeList now contains a list of <dvp:entry> nodes.
string folderName = xmlNode.Attributes["value"].ToString().Trim();
folderNames.Add(folderName);
}
However, this code returns an empty xmlNodeList, so the final loop has no items.
I'm not sure how to use the XmlNamespaceManager to pick up the "dvp" prefix, or whether it figures this out when it loads the XmlDocument from the XML on disk.
Can anyone give me some guidance how one goes about using xpath to retrieve values for xml with prefixed nodes? Unfortunately I do not have the power to change the format of the XML so I have to work with the xml I'm provided with.
thanks heaps,
David.
you can ignore the namespace using local-name()
XmlNodeList xmlNodeList =
doc.SelectNodes("/*[local-name()='systemConfig']/*[local-name()='map'][#id='folderMappings']");

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']");

Replace xml document parameters using c#

I want to replace following #eleval2,#eleval4 parameters with some other values using c#.net.Please help me to do it.
<root>
<element1>
<element2>
#eleval2
</element2>
</element1>
<element3>
<element4>
<element4>
#eleval4
</element4>
</element4>
</element3>
Directly updating node:
XmlDocument xml = new XmlDocument();
xml.Load("file_name.xml");
xml.SelectSingleNode("/root/element1/element2").InnerText = "NewValue";
For looping:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("path_here");
XmlNodeList tagNodes= xmlDoc.GetElementsByTagName("tag_of_your_interest");
//Loop through first child of above list
foreach (XmlNode chapter in tagNodes[0].ChildNodes)
{
//Perform your updates here
}
Load from string:
XmlDocument doc = new XmlDocument();
doc.LoadXml(str);
Get all list of nodes matches path:
XmlNodeList xnList = doc.SelectNodes("/sections/notebooks/article");

Trying to change a XML node with no success

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);

Make XML in c# with namespaces

I need to generate XML in the following form:
<ns1:root xmlns:ns1="http://example.com/xmlns1" xmlns:ns2="http://example.com/xmlns2">
<ns2:item ns2:param="value" />
</ns1:root>
I use this code:
XmlDocument xDoc = new XmlDocument();
XmlElement xRootElement = (XmlElement)xDoc.AppendChild(xDoc.CreateElement("ns1:root"));
xRootElement.SetAttribute("xmlns:ns1", "http://example.com/xmlns1");
xRootElement.SetAttribute("xmlns:ns2", "http://example.com/xmlns2");
XmlElement xElement = (XmlElement)xRootElement.AppendChild(xDoc.CreateElement("ns2:item"));
xElement.SetAttribute("ns2:param", "value");
But the result is the following:
<root xmlns:ns1="http://example.com/xmlns1" xmlns:ns2="http://example.com/xmlns2">
<item param="value" />
</root>
Thanks for the advice.
XmlElement xElement = (XmlElement)xRootElement.AppendChild(xDoc.CreateElement("ns2:item", "http://example.com/xmlns2"));
Gave me:
<root xmlns:ns1="http://example.com/xmlns1" xmlns:ns2="http://example.com/xmlns2">
<ns2:item param="value" />
</root>
By the way, "ns2:param" is not necessary. XML attributes belong to the same namespace as the element.
Try this:
XmlDocument xDoc = new XmlDocument();
XmlElement xRootElement = (XmlElement)xDoc.AppendChild(xDoc.CreateElement("ns1:root"));
xRootElement.SetAttribute("xmlns:ns1", "http://example.com/xmlns1");
xRootElement.SetAttribute("xmlns:ns2", "http://example.com/xmlns2");
XmlElement xElement = (XmlElement)xRootElement.AppendChild(xDoc.CreateElement("item", "http://example.com/xmlns1"));
xElement.SetAttribute("param", "http://example.com/xmlns1", "value");

Categories

Resources