Insert node in xml document using c#

允我心安 提交于 2019-12-02 06:43:44

问题


I was trying to insert an XML node in XML document at a specific position.

This is my xml:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
</Envelope>

And am trying to insert another tag <productGroups>0093</productGroups> below to the tag <productGroups>0085</productGroups>

Expecting like the below:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <productGroups>0093</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
</Envelope>

Used the below C# code to achieve it.

XmlDocument doc = new XmlDocument();
string inputxml = this.StServiceCallActivity5.InputEnvelope.InnerXml.ToString();
//Here inputxml contains whole xml document.
string addxml = "<productGroups>0093</productGroups>";
doc.LoadXml(inputxml);
XmlDocumentFragment xmlDocFrag = doc.CreateDocumentFragment();
xmlDocFrag.InnerXml = addxml;
XmlElement parentEle = doc.DocumentElement;
parentEle.AppendChild(xmlDocFrag);

And it returns value like

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <productGroups>0093</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
    <productGroups xmlns="">0093</productGroups>
</Envelope>

Am a newbie to C# code, kindly help me to get the XML doc as expected. your help is much appreciated.


回答1:


When you do this:

XmlElement parentEle = doc.DocumentElement;
parentEle.AppendChild(xmlDocFrag);

You're appending the node to the root of the document. You probably wanted to select the actual readContract node that the item is supposed to be appended into. As an example:

XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "productGroup", "");
newNode.InnerText = "something";

XmlNode readContractNode = doc["Envelope"]["Body"]["readContract"];
XmlElement groups = readContractNode["productGroups"];
readContractNode.InsertAfter(newNode, groups);

Of course you'd probably want to handle the case where there are already multiple child productGroup elements, but the idea is the same.




回答2:


Looks like namespaces are causing the problem. This worked for me:

XmlDocument doc = new XmlDocument();
doc.LoadXml(File.ReadAllText("XMLFile1.xml"));
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("ns1", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("ns2", "http://implementation.company.schema.reference");
var rootNode = doc.SelectSingleNode("//ns1:Envelope", ns);
var readContractNode = rootNode.FirstChild.FirstChild;
var newNode = doc.CreateNode(XmlNodeType.Element, "productGroups", "http://implementation.company.schema.reference");
newNode.InnerText = "0093";
readContractNode.InsertAfter(newNode, readContractNode.SelectSingleNode("//ns2:productGroups", ns));

Or if you don't fancy namespaces like I me, you can try a bit more "brute-forcy" approach:

XmlDocument doc = new XmlDocument();
doc.LoadXml(File.ReadAllText("XMLFile1.xml"));
var newNode = doc.CreateNode(XmlNodeType.Element, "productGroups", "http://implementation.company.schema.reference");
newNode.InnerText = "0093";
doc.FirstChild.FirstChild.FirstChild.InsertAfter(newNode, doc.FirstChild.FirstChild.FirstChild.FirstChild.NextSibling);

It can be optimized but I think it helps to make the point that root cause is the different namespaces in the document.




回答3:


You may want to use XmlNode.InsertAfter Method.

public virtual XmlNode InsertAfter(
    XmlNode newChild,
    XmlNode refChild
)

Where

newChild = The XmlNode to insert

and

refChild = The XmlNode that is the reference node. The newNode is placed after the refNode

Please check this link for information.

And check this link with answer on SO.

P.S.
Always check other answers before posting new question.



来源:https://stackoverflow.com/questions/32097267/insert-node-in-xml-document-using-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!