0

I want to read the xml elements dynamically (I mean without hard-coding the element name) from the xml file. I am not able to use the XmlReader.ReadToDescendant method as it expects a Local Name which in my case varies. For example in this case I need to read elements A, B, C, D & etc...

<?xml version="1.0" encoding="UTF-8"?>
<test Version="2010" xmlns="http://test.org/2010/values">
<A>
    <Data>
     <Somedata></Somedata>
    </Data>
    <Rows>
      <Row></Row>
      <Row></Row>
    </Rows>
</A>
<B>
    <Data>
     <Somedata></Somedata>
    </Data>
    <Rows>
      <Row></Row>
      <Row></Row>
    </Rows>
</B>
<C>
    <Data>
     <Somedata></Somedata>
    </Data>
    <Rows>
      <Row></Row>
      <Row></Row>
    </Rows>
</C>
<D>
    <Data>
     <Somedata></Somedata>
    </Data>
    <Rows>
      <Row></Row>
      <Row></Row>
    </Rows>
</D>
</test>

Please help me.

1
  • where are you going to get the names to read then? from another file or from a database? Commented Oct 31, 2011 at 21:42

2 Answers 2

5

That's pretty simple:

XDocument doc = XDocument.Load("test.xml");
string name = GetNameFromWherever();
foreach (XElement match in doc.Descendants(name))
{
    ...
}

That's using LINQ to XML - a lovely API for XML if you're using .NET 3.5 or later... it's much nicer than using XmlReader.

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

4 Comments

Thanks for your response. In case if I dont know the elements, Is there any way we can get the data from the XmlDocument dynamically?
@user972255: It's not clear what you mean - this is fetching the elements based on a name which can be fetched at execution time, e.g. by asking the user.
Ok. If you have more than one name then we need to have another loop on top of the descendants loop to get the names one by one?
@user972255: That would be the simplest approach, yes - or you could just use doc.Descendants().Where(x => names.Contains(x.Name.LocalName)).
0

For dynamic generation of XML content into another set of classes you could do something like this:

class GenericNode
{
  private List<GenericNode> _Nodes = new List<GenericNode>();
  private List<GenericKeyValue> _Attributes = new List<GenericKeyValue>();
  public GenericNode(XElement Element)
  {
     this.Name = Element.Name;
     this._Nodes.AddRange(Element.Elements()
                                 .Select(e => New GenericNode(e));
     this._Attributes.AddRange(
                Element.Attributes()
                       .Select(a => New GenericKeyValue(a.Key, a.Value))
  }

  public string Name { get; private set; }
  public IEnumerable<GenericNode> Nodes
  {
    get
    {
       return this._Nodes;
    }       
  }
  public IEnumerable<GenericKeyValue> Attributes
  {
    get
    {
       return this._Attributes;
    }
  }
}

class GenericKeyValue
{
  public GenericKeyValue(string Key, string Value)
  {
     this.Key = Key;
     this.Value = Value;
  }
  public string Key { get; set; }
  public string Value { get; set; }
}

Then you simply:

XElement rootElement = XElement.Parse(StringOfXml); // or
XElement rootElement = XElement.Load(FileOfXml);

GenericNode rootNode = new GenericRode(rootElement);

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.