Insert node in xml document using c#

2020-04-20 15:33发布

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.

标签: c# xml hp-uft
3条回答
神经病院院长
2楼-- · 2020-04-20 16:08

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.

查看更多
可以哭但决不认输i
3楼-- · 2020-04-20 16:10

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.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-04-20 16:14

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.

查看更多
登录 后发表回答