0

How do I iterate over all the elements of the XML tree, and access to them? What I mean is that the input gets unknown xml file, and the code itself it iterates not knowing the number of elements and branches.

I know that was a lot of answers on such topics and the solution was ready to implement the code, where the known structures xml.

This is a code which i am using:

class Program
 {
    static void Process(XElement element)
    {
        if (!element.HasElements)
        {
            Console.WriteLine(element.GetAbsoluteXPath());
        }
        else
        {
            foreach (XElement child in element.Elements())
            {
                Process(child);
            }
        }
    }}

static void Main()
    {



         var doc = XDocument.Load("C:\\Users\\Błażej\\Desktop\\authors1.xml");
        List<string> elements = new List<string>();
       Program.Process(doc.Root);

           Console.ReadKey();

}
 public static class XExtensions
{
    public static string GetAbsoluteXPath(this XElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        Func<XElement, string> relativeXPath = e =>
        {
            int index = e.IndexPosition();
            string name = e.Name.LocalName;

            return (index == -1) ? "/" + name : string.Format
            (
                "/{0}[{1}]",
                name,
                index.ToString()
            );
        };

        var ancestors = from e in element.Ancestors()
                        select relativeXPath(e);

        return string.Concat(ancestors.Reverse().ToArray()) +
               relativeXPath(element);
    }

    public static int IndexPosition(this XElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        if (element.Parent == null)
        {
            return -1;
        }

        int i = 1; 

        foreach (var sibling in element.Parent.Elements(element.Name))
        { // czyli patrzymy na rodzeństwo, czy występują podobne np. au_id[1], au_id[2]
            if (sibling == element)
            {
                return i;
            }
            else
            {
               i++;
            }


        }

        throw new InvalidOperationException
            ("element has been removed from its parent.");
    }

Now how can i add some elements to exisitng nodes by iterate ? It's possible ?

Błażej Rejnowski
  • 239
  • 1
  • 2
  • 8
  • 1
    If the schema of XML is not known, though possible, it will be like too much of a code. You can use XMLDocument or XPATHDocument. Or in case of LINQ use XDocument which will allow you to read the XML. – A3006 Sep 22 '16 at 08:11
  • It may help to know exactly what you are trying to achieve. – PaulF Sep 22 '16 at 08:21
  • I need a method that iterates me all the elements of the tree xml . The idea is to make the code work universally on various branches in the xml files . – Błażej Rejnowski Sep 22 '16 at 08:27
  • @MikeEvans - What is the end goal? How you want to use this data? – A3006 Sep 22 '16 at 08:35
  • I want to be able to add the item to the branched node ( for example : authors / au_id /.../..../../ address) , and sometimes I want to change it or to add it to another node . It may be that there will be some of the same branch , and I want to choose the iteration in which to make a difference and where not .To change something I do not want all the time to type a very long paths. – Błażej Rejnowski Sep 22 '16 at 08:46
  • Look at this recursive answer : http://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng Sep 22 '16 at 09:18
  • Your description is too general to be answered well. Do you know which nodes you want to edit in the xml or are you inserting xml at random? Use XmlDocument.Load(file) and then iterate the child nodes of each XmlNode, or CreateNavigator() and there are a bunch of Move...() methods there. – strongbutgood Sep 22 '16 at 09:19

1 Answers1

0

As @strongbutgood mentioned, this is very generic. May be below generic code helps

Dim xdoc As New XDocument();
xdoc = XDocument.Parse(myXML);

// Adding new element
xdoc.Element(<Your_Parent_Node_Name>).Add(new XElement("<New_Element_Name>", "<New_Element_Value>"));

// Deleting existing element
 xdoc.Descendants().Where(s =>s.Value == "<Element_To_Be_Removed>").Remove(); 

Hope this helps.

Please note that this is a generic answer and you will need to re-write as per your needs

A3006
  • 1,051
  • 1
  • 11
  • 28
  • Ok, so i will show you : And you see we have 3 times this same node. I want to add element to (in second node) and how can i refer to in second node ? – Błażej Rejnowski Sep 22 '16 at 09:43
  • @MikeEvans - This is not possible unless you have one of following 1) ID for the "authors" element OR 2) Exact location (like 2nd) – A3006 Sep 22 '16 at 09:47
  • If you are sure it will always be the 2nd node, you can do that in the loop and make changes when the counter hits 2. But having ID as an attribute to "authors" will be correct approach. – A3006 Sep 22 '16 at 09:48