xsharp.eu • How to get an array with XML tags within only 1 node
Page 1 of 1

How to get an array with XML tags within only 1 node

Posted: Sun Oct 08, 2023 7:57 pm
by ic2
This sounds simple but I have tried multiple solutions I found but none gave me what I want. Consider the XML file below. What I want is the "pos" tags below of a certain zoom factor. So for Zoom200 I want 10, 20 and 30 in a 3 element array.

I found (C# samples):

Code: Select all

XDocument doc = XDocument.Load(cPDFName);

var allElements = doc.Descendants("Zoom200").Select(element => element.Value).ToArray();
string[]AllPos = doc.Descendants("pos").Select(n => n.Value).ToArray();
var allnodes2 = doc2.SelectNodes("//Zoom200");

The first line returns allElemens but this is only 1 array element with all "pos" values in 1 line
The second line returns a string array with all requested "pos" values but it also includes for all zoom values for Zoom300
The third lines returns the contents of Zoom200 but how to get these "pos" values from it? InnerText is also 1 line (with "10-20-30") instead of an array of these 3 values.

It must be something simple I overlook or couldn't find.

Dick


<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Doc>
<Zoom200>
<pos>10</pos>
<pos>20</pos>
<pos>30</pos>
</Zoom200>
<Zoom300>
<pos>100</pos>
<pos>200</pos>
<pos>300</pos>
</Zoom300>
</Doc>

Re: How to get an array with XML tags within only 1 node

Posted: Mon Oct 09, 2023 10:32 am
by VR
Hi,

this is how ChatGPT would do it...

Code: Select all

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        // Load the XML data from your file or string
        string xmlData = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
                            <Doc>
                                <Zoom200>
                                    <pos>10</pos>
                                    <pos>20</pos>
                                    <pos>30</pos>
                                </Zoom200>
                                <Zoom300>
                                    <pos>100</pos>
                                    <pos>200</pos>
                                    <pos>300</pos>
                                </Zoom300>
                            </Doc>";

        // Parse the XML data
        XDocument doc = XDocument.Parse(xmlData);

        // Specify the zoom factor you want (e.g., "Zoom200")
        string targetZoom = "Zoom200";

        // Find the <Zoom> element with the specified factor
        XElement zoomElement = doc.Root.Elements(targetZoom).FirstOrDefault();

        if (zoomElement != null)
        {
            // Extract the <pos> elements under the specified <Zoom> element
            var posElements = zoomElement.Elements("pos").Select(e => int.Parse(e.Value)).ToArray();

            // Now, posElements contains the values (10, 20, 30) for Zoom200
            Console.WriteLine("Values for " + targetZoom + ": " + string.Join(", ", posElements));
        }
        else
        {
            Console.WriteLine(targetZoom + " not found.");
        }
    }
}

Re: How to get an array with XML tags within only 1 node

Posted: Mon Oct 09, 2023 8:50 pm
by ic2
Hello Volmar,

A nice idea. I tried some ChatGPT queries and some look quite clever. I tried the program and it actually compiled. So far so good. But on running I got an exception System.FormatException: 'Input string was not in a correct format.' That is already a bit less clever.

I modified it as follows:

Code: Select all

var posElements = zoomElement.Elements("pos").Select(e => e.Value.ToArray());
to avoid the Parse causing the exception. I do get all values but it says all -literally- system.char instead of the values (10, 20, 30 in my posted sample). I inspected posElements The result view from the debugger of the elements (in my test XML I have got 5 values) actually contains the correct 'pos' values. See picture; the second pos tag in my actual XML is: <pos>2177,28</pos> and what I see is 50'2' 49'1' etc. No idea what the 50,49 etc mean but the second part forms indeed 2 1 7 7 , 2 8 (right of the red line)
XS3472RersultView.jpg
XS3472RersultView.jpg (30.38 KiB) Viewed 2513 times
Unfortunately I can't figure out how to retrieve these values as 2177,28 and the other values I've got in the XML. Or what to ask ChatGPT to have this solved :?

Dick

Re: How to get an array with XML tags within only 1 node

Posted: Tue Oct 10, 2023 8:03 am
by VR
Hi Dick

Code: Select all

var posElements = zoomElement.Elements("pos").Select(e => e.Value.ToArray());
e.Value is a string -> e.Value.ToArray() gives you every char of the string as array. Try this instead:

Code: Select all

var posElements = zoomElement.Elements("pos").Select(e => e.Value).ToArray();
Volkmar

Re: How to get an array with XML tags within only 1 node

Posted: Tue Oct 10, 2023 12:17 pm
by ic2
Yes, that works! Lambda expressions are still a bit of a black box for me. It is very interesting that this is solved by a bit of ChatGPT (and an important bit of Volkmar).

What strikes me is that I would have expected a more direct way to retrieve these values in either the XmlDocument or XDocument class.

Anyway, thanks!

Dick

Re: How to get an array with XML tags within only 1 node

Posted: Wed Oct 11, 2023 8:38 am
by VR
Hi...

The "one-liner" for this operation is

Code: Select all

var posElements = doc.Root.Element("Zoom200")?.Elements("pos").Select(e => e.Value).ToArray() ?? Array.Empty<string>();
ChatGPT tends to write code in a more verbose way.

Re: How to get an array with XML tags within only 1 node

Posted: Wed Oct 11, 2023 9:35 am
by ic2
Indeed, but although I already made it a bit shorter, I tend to avoid oneliners as I prefer that I actually understand what the code is doing. Once again, I was quite impressed what ChatGPT produced (I didn't find a working sample in the usual websites) even though the actual result didn't work - but it was close.

Dick