0

I am trying to generate XML in the following format:

<ImportSession>
  <Batches>
    <Batch>
      <BatchFields>
        <BatchField Name="Field1" Value="1" />
        <BatchField Name="Field2" Value="2" />
        <BatchField Name="Field3" Value="3" />
      </BatchFields>
    <Batch>
  <Batches>
</ImportSession>

I have the following code:

XmlDocument doc = new XmlDocument();
XmlElement importSession = doc.CreateElement("ImportSession");
XmlElement batches = doc.CreateElement("Batches");
XmlElement batch = doc.CreateElement("Batch");
XmlElement batchFields = doc.CreateElement("BatchField");
doc.AppendChild(importSession);

XmlNode importSessionNode = doc.FirstChild;
importSessionNode.AppendChild(batches);

XmlNode batchesNode = importSessionNode.FirstChild;
batchesNode.AppendChild(batch);
XmlNode batchNode = batchesNode.FirstChild;

int numBatchFields = 9;
for (int j = 0; j < numBatchFields; j++)
{
    batchNode.AppendChild(batchFields);

    XmlElement batchfields = (XmlElement)batchNode.FirstChild;
    batchfields.SetAttribute("Name", "BatchPrevSplit");
    batchfields.SetAttribute("Value", j.ToString());
}

My problem is that It doesnt add the batchfield tags. It adds one so I get:

<ImportSession>
  <Batches>
    <Batch>
      <BatchField Name="BatchPrevSplit" Value="8" />
    </Batch>
  </Batches>
</ImportSession>

It seems because I am trying to add the same Child element to the batchNode Node that it just overwrites the data in the existing tag. I tried putting in

XmlElement batchfields = (XmlElement)batchNode.ChildNodes.Item(j);

instead of

XmlElement batchfields = (XmlElement)batchNode.FirstChild; 

but it doesnt append another Child to the batchNode if i use the same element so there is only 1 child. So can anyone tell me how I can achieve this?

4
  • Why are you doing it in this fashion? Can you not do with with Serialization ? Commented Oct 7, 2015 at 14:00
  • Im generating an xml that will be imported into an application and it expects a specific format. The batchfields need to be in that format Commented Oct 7, 2015 at 14:03
  • XmlElement batchFields = doc.CreateElement("BatchField"); shouldn't that be BatchFields? Looks like you are missing an element, this one is named wrong, and you need to add a BatchField element. Commented Oct 7, 2015 at 14:04
  • I don't think it's worthy of an answer by itself, but if you're interested in using serialization, you can use xmltocsharp.azurewebsites.net to generate class definitions that can be serialized into the desired XML format. There's a similar one for JSON: json2csharp.com Commented Oct 7, 2015 at 14:10

2 Answers 2

3

Rewrite your for loop like this:

for (int j = 0; j < numBatchFields; j++)
{
    XmlElement batchFields = doc.CreateElement("BatchField");
    batchFields.SetAttribute("Name", "BatchPrevSplit");
    batchFields.SetAttribute("Value", j.ToString());

    batchNode.AppendChild(batchFields);
}
Sign up to request clarification or add additional context in comments.

3 Comments

I think you accidentally a line. ;)
@JoshuaShearer Thanks!
Great man thanks. Make a lot of sense. Changing the information before appending so the tag will be different. Cheers
3

LINQ to XML will save you pain...

var xml = new XElement("ImportSession",
    new XElement("Batches",
            new XElement("Batch",
                new XElement("BatchFields",
                    from j in Enumerable.Range(0,9)
                    select new XElement("BatchField",
                        new XAttribute("Name", string.Format("Field{0}", j)),
                        new XAttribute("Value", j)
                        )
                    )
                )
        )
    );

4 Comments

I was initially using that but there are 100 meta data fields so it just got too big and awkward, id rather do it programmatically.
That's up to you... you can easily do linq with conditional logic as well. xElement.Add(new XAttribute("attr", val))
@discodowney That statement doesn't make any sense. Linq to XML is just a different (and better) DOM for working with XML. Anything you can do with the old DOM you can usually do with less code in Linq to XML.
yeah your right. I misread his post. Sorry. I didnt know you could do the Enumerable thing. That is a better approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.