0

Here is my XML,

<content id = "C1">
<paragraph >
      <Info />
      <contentValue>Content1</contentValue>
</paragraph>

<paragraph>
      <Info />
      <contentValue>Content2</contentValue>
</paragraph>
<content>

<content id = "C2">
<paragraph >
      <Info />
      <contentValue>Content3</contentValue>
</paragraph>

<paragraph>
      <Info />
      <contentValue>Content4</contentValue>
</paragraph>

<paragraph>
      <Info />
      <contentValue>Content5</contentValue>
</paragraph>
<content>

I need to parse through each of <content> tags and fetch the values of <contentvalue> tags and store it in a List.

I'm using following code but, values of <contentvalue> tags are concatinated like 'Content1Content2'

var xdoc = XDocument.Load(path);
var Contents = xdoc.Descendants("content").Select(c => (string)c).ToArray();

3 Answers 3

1

Couple of things I noticed:

  1. Your XML is not in a correct format
  2. You are trying to select Content node and render it as string, which is wrong

XML:

<root>
    <content id="C1">
        <paragraph>
            <Info/>
            <contentValue>Content1</contentValue>
        </paragraph>
        <paragraph>
            <Info/>
            <contentValue>Content2</contentValue>
        </paragraph>
    </content>
    <content id="C2">
        <paragraph>
            <Info/>
            <contentValue>Content3</contentValue>
        </paragraph>
        <paragraph>
            <Info/>
            <contentValue>Content4</contentValue>
        </paragraph>
        <paragraph>
            <Info/>
            <contentValue>Content5</contentValue>
        </paragraph>
    </content>
</root>

Code:

var Contents = xdoc.Descendants("content").Descendants("paragraph").Select(i => i.Element("contentValue").Value).ToList();

Above code exactly selects contentValue node under paragraph.

Sign up to request clarification or add additional context in comments.

2 Comments

Siva Charan - Also require the contentID along with the values.
@Raghavendra: In that case, what is the expected output on the list
1

If you don't want your <contentValue>s to be grouped by the <content> tag, just try:

V1

var Contents = xdoc.Descendants("contentValue").Select(c => (string)c).ToArray();

or V2

var Contents = xdoc.Root.XPathSelectElements("content/paragraph/contentValue")
       .Select(x => x.Value).ToList();

NOTE that for using the V2 solution you need to add a reference to the System.Xml.XPath namespace.


(This next section represents a different solution, for a different but similar case, provided for reference purposes) Otherwise, if you need to get the values grouped by the <content> tag, you could try:

var grouped = xdoc.Descendants("contentValue")
       .Select(x => new { PNode = x.Ancestors("content")
       .FirstOrDefault().Attribute("id").Value, CNode = x.Value })
       .GroupBy(x => x.PNode).ToDictionary(x => x.Key, y => y.ToList());

This then can be iterated as follows:

foreach (var group in grouped)
{
     Console.WriteLine("content id = " + group.Key);
     foreach (var singleCValue in group.Value)
     {
          Console.WriteLine(singleCValue.CNode);
     }
}

5 Comments

Why are you doing this in such a complex way. Refer my answer
@SivaCharan, please read my post carefully. The solution to the question is the very first line of code. It iterated the descendants of the node only once, which is not complex at all. You iterate them twice. I start my post stating that the solution to come is for the case in which @Raghavendra does not need the values grouped by the <content> node. The second part of my answer provides a solution for grouping the <contentValue> node values by the corresponding <content> node. Therefore I'm providing two solutions, for two very distinct situations, as the OP did not specify the case.
Your first line of code itself wrong. It will fail, if there is a contentValue node outside paragraph node. Please have a understanding of how xdoc.Descendants("contentValue") works.
@SivaCharan, please be respectful. I did not insult you, and I used an appropriate tone. My answer is in the context of the provided XML.
My friend I'm helping you in understand the concept. So I don't have any intention to hurt you :). Sorry if I have make you to feel bad.
0

I guess your tags are not well formed. You can do something like this.

 XDocument doc = XDocument.Load(path);

            IList<string> list=new List<string>();

            IEnumerable<XElement> contentElements = doc.Descendants("content");//this get all "content" tags
            IEnumerable<XElement> contentValueElements = contentElements.Descendants("contentValue");//this get all "contentValue" tags

            foreach (XElement i in contentValueElements)
            {

                    list.Add(i.Value);
            }

Comments

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.