Reading XML data using XmlDocument with C# - 读取属性数据并拆分结果

Reading XML data using XmlDocument with C# - Reading attribute data and splitting the results

我正在尝试使用 XmlDocument 读取一些 XML 数据并遇到一些挑战。

我的问题如下:

  1. 当我尝试获取 bfihost 值时,它为我提供了 bfihostpropwetsaar 元素值组合为一个输出。为什么会这样,我如何才能得到 bfihost?

  2. 每个 Depth 元素都有一个名为 duration 的属性。我的第一个 foreach 循环将字符串 durationString 写入控制台,但它似乎没有在 XmlNode chldNode 中找到任何名为 duration 的属性。

  3. 这个问题可能不太重要,但是当我找到元素 ReturnPeriods 的值时,例如我只能检索所有用逗号分隔的值。这不是问题,因为我刚刚使用 Split(',') 方法并将其分配给一个数组并循环遍历它。我很好奇 XmlDocument 是否有更优雅的方式来做到这一点?

感谢您提供的任何帮助。

这是 XML 数据的精简版。 , ... 已添加,因为实际 xml 文件中有更多数据。

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<FEHCDROMExportedDescriptors appVersion="2.0.0.0" version="2.0.1">
    <PointDescriptors y="111111" x="222222" grid="GB">
        <bfihost>0.386</bfihost>
        <propwet>0.3</propwet>
        <saar>643</saar>
    </PointDescriptors>
    <PointDDF2013Values>
        <ReturnPeriods>
            <![CDATA[
                1.3, 1.58, 2, ...
            ]]>
        </ReturnPeriods>
        <Depths duration="0.083">
            <![CDATA[
                3.27693489525396, 3.98688804941076, 4.68688804941076, ...
            ]]>
        </Depths>
        <Depths duration="0.25">
            <![CDATA[
                5.37693489525396, 6.51484587430874, 7.81484587430874, ...
            ]]>
        </Depths>
        <Depths duration="0.5">
            <![CDATA[
                6.87693489525396, 8.38688804941076, 10.0017339237195, ...
            ]]>
        </Depths>
    </PointDDF2013Values>
</FEHCDROMExportedDescriptors>

我写的代码如下:

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(file);

            XmlTextReader reader = new XmlTextReader(file);
            XmlNode node = xmlDoc.ReadNode(reader);

            string durationString;
            foreach (XmlNode chldNode in node.ChildNodes)
            {
                //Read the attribute duration
                if (chldNode.Name == "Depths")
                {
                    if (chldNode.HasChildNodes)
                    {
                        foreach (XmlNode item in node.ChildNodes)
                        {
                            durationString = chldNode.Attributes["duration"].Value;
                            Console.WriteLine("durations[]: " + durationString);

                        }
                    }
                }
            }


            XmlNodeList pointDescriptors = xmlDoc.GetElementsByTagName("PointDescriptors");
            XmlElement xmlElement = (XmlElement)pointDescriptors[0];

            // Get coordinates
            XmlAttribute y = xmlElement.GetAttributeNode("y");
            Console.WriteLine("y[]: " + y.InnerXml);
            XmlAttribute x = xmlElement.GetAttributeNode("x");
            Console.WriteLine("x[]: " + y.InnerXml);

            // for some reason returns the bfi Host, propwet and saar
            XmlNodeList bfihost = xmlDoc.GetElementsByTagName("bfihost");
            Console.WriteLine("bfihost[]: " + pointDescriptors[0].InnerText);

            // returns all return periods as a string.
            XmlNodeList returnPeriods = xmlDoc.GetElementsByTagName("ReturnPeriods");
            //Console.WriteLine("Return Periods[]: " + returnPeriods[0].InnerText);

            //I can split the string by commas and remove white spaces as follows
            string[] returnPeriodsArray = returnPeriods[0].InnerText.Split(',').Select(sValue => sValue.Trim()).ToArray();
            foreach (string s in returnPeriodsArray)
            {
                //System.Console.Write("{0} ", s);
            }

            int k = 0;
            //Loop through all the depths, and split the results
            XmlNodeList depths = xmlDoc.GetElementsByTagName("Depths");
            XmlAttribute duration;
            for (int i = 0; i < depths.Count; i++)
            {
                if (depths[i].InnerText.Length > 0)
                {
                    
                    System.Console.Write("{0} ", "\n\n" + "Depth xxx" + "\n\n");
                    string[] depthsArray = depths[i].InnerText.Split(',').Select(sValue => sValue.Trim()).ToArray();
                    foreach (string s in depthsArray)
                    {
                        System.Console.Write("{0} ", "(" + returnPeriodsArray[k] + ") - " + s + "\n");
                        k++;
                        if (k > 21)
                        {
                            k = 0;
                        }
                    }
                
                }
            }

我得到的输出是:

y[]: 11111 //correct
x[]: 22222 //correct
bfihost[]: 0.3860.3643 //this is combination of three elements for some reason?

///Here I try to get the depth data but nothing is returned.

Depth xxx // xxx is just a place holder until I can fix the above issue.

 (1.3) - 3.27693489525396 //all these outputs are correct.
 (1.58) - 3.98688804941076
 (2) - 4.68688804941076


Depth xxx

 (1.3) - 5.37693489525396
 (1.58) - 6.51484587430874
 (2) - 7.81484587430874



Depth xxx

 (1.3) - 6.87693489525396
 (1.58) - 8.38688804941076
 (2) - 10.0017339237195

最好用LINQ来XML API。它自 2007 年起在 .Net Framework 中可用。

c#

void Main()
{
    const string fileName = @"e:\Temp\FEHCDROME.xml";
    XDocument xdoc = XDocument.Load(fileName);
    
    XElement xelem = xdoc.Descendants("PointDescriptors").FirstOrDefault();

    Console.WriteLine("PointDescriptors:");
    Console.WriteLine("y[]: {0}", xelem.Attribute("y").Value);
    Console.WriteLine("x[]: {0}", xelem.Attribute("x").Value);
    Console.WriteLine("bfihost[]: {0}", xelem.Element("bfihost").Value);

    XElement rp = xdoc.Descendants("ReturnPeriods").FirstOrDefault();
    Console.WriteLine("{0}ReturnPeriods:", Environment.NewLine);
    foreach (string s in rp.Value.Split(',').Select(sValue => sValue.Trim()).ToArray())
    {
        Console.WriteLine("{0} ", s);
    }

    Console.WriteLine("{0}Depths:", Environment.NewLine);
    foreach (XElement dp in xdoc.Descendants("Depths"))
    {
        foreach (string s in dp.Value.Split(',').Select(sValue => sValue.Trim()).ToArray())
        {
            Console.WriteLine("{0} ", s);
        }
    }
}

输出

PointDescriptors:
y[]: 111111
x[]: 222222
bfihost[]: 0.386

ReturnPeriods:
1.3 
1.58 
2 
... 

Depths:
3.27693489525396 
3.98688804941076 
4.68688804941076 
... 
5.37693489525396 
6.51484587430874 
7.81484587430874 
... 
6.87693489525396 
8.38688804941076 
10.0017339237195 
...