0

I am using c# to create a xml file, however I got some problem. I would like to have both of parent and child nodes with a same attribute. But only one of those nodes has the attribute, even though I appended both of those.

what I expected:

<request>
    <transaction transactionId:"123">
        <transactionDetail transactionId:"123"></transactionDetail>
    </transaction>
</request>

what I got:

<request>
    <transaction>
        <transactionDetail transactionId:"123"></transactionDetail>
    </transaction>
</request>

or

<request>
    <transaction  transactionId:"123">
        <transactionDetail></transactionDetail>
    </transaction>
</request>

This is depends on the order that I write code (The node I append later has attribute). Could you please help me out to find what's causing this problem?

Also, I just wonder:

Does the order of appending (both of .AppendChild() & .Append() ) matter?

Can't I reuse attributes which are already appended in other nodes?

The following is the function to create xml file:

public ActionResult createXMLFile() {

            XmlDocument xmlFile = new XmlDocument();

            XmlNode request = xmlFile.CreateElement("request");
            XmlNode transaction= xmlFile.CreateElement("transaction");
            XmlNode transactionDetail= xmlFile.CreateElement("transactionDetail");


            XmlAttribute transactionId= xmlFile.CreateAttribute("transactionId");
            transactionId.Value = "123";

            transaction.Attributes.Append(transactionId);
            transactionDetail.Attributes.Append(transactionId);

            xmlFile.AppendChild(request);
            request.AppendChild(transaction);
            transaction.AppendChild(transactionDetail);

            string path ="somepath";

            xmlFile.Save(path);

    }

Thank you for reading my question. :)

pebble
  • 59
  • 9
  • 2
    You will need to clone the object. `XmlDocument` will have some odd behavior if you try reusing the same object on two different XML elements. – Jessie Mar 29 '17 at 18:53
  • @user2896976 Ohh do I need to do so? That is sad when I have tens of elements to clone... But still, Thank you for letting me know and for your fast comment! :) If you put this as answer, I will accept it – pebble Mar 29 '17 at 19:24
  • 2
    @user2896976 is correct, you must use a separate `XmlAttribute` each time. `XmlAttribute` has a [`ParentNode`](https://msdn.microsoft.com/en-us/library/system.xml.xmlattribute.parentnode.aspx) property which is why the same instance cannot be used multiple times in the DOM hierarchy. – dbc Mar 29 '17 at 20:13

1 Answers1

1

As hinted in the comments, you need to create two attributes, you can't reuse the same one:

var transactionId1 = xmlFile.CreateAttribute("transactionId");
transactionId1.Value = "123";
transaction.Attributes.Append(transactionId1);

var transactionId2 = xmlFile.CreateAttribute("transactionId");
transactionId2.Value = "123";
transactionDetail.Attributes.Append(transactionId2);

However, I'd suggest using LINQ to XML. You can create this XML far more declaratively:

var doc = new XDocument(
    new XElement("request",
        new XElement("transaction", 
            new XAttribute("transactionId", "123"),
                new XElement("transactionDetail", new XAttribute("transactionId", "123"))
            )
        )
    );

doc.Save(path);

See this fiddle.

Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Hello, @CharlesMager. Thank you for the answer. However, since I am not familiar with the .net environment, could you please tell me what will be the biggest difference of using LINQ to XML? This structure seems way better than what I did, but I wonder what is happening in the computer... By putting `using System.Xml.Linq;` am I adding something like a library of java or source code in js?? – pebble Mar 30 '17 at 15:11
  • 1
    It does require referencing a separate assembly, but it's part of the framework so it doesn't need including when you deploy. `XmlDocument` is part of the 'classic' DOM API that's been around since .NET was released whereas LINQ to XML is a newer API that was added with .NET 3.5 and is *far* nicer to use. [This question](http://stackoverflow.com/questions/1542073/xdocument-or-xmldocument) covers it better than I can in a comment. – Charles Mager Mar 30 '17 at 15:18
  • Thank you for the reference! It is still confusing, but now I've got better understanding of it. I tried with the LINQ to XML and it is much faster to do code. Thanks again, and have a good day :) – pebble Mar 30 '17 at 15:57