【问题标题】:Reading XML data using XmlDocument with C# - Reading attribute data and splitting the results使用带有 C# 的 XmlDocument 读取 XML 数据 - 读取属性数据并拆分结果
【发布时间】:2021-06-03 03:34:23
【问题描述】:

我正在尝试使用 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

【问题讨论】:

    标签: c# xml xmldocument


    【解决方案1】:

    最好使用 LINQ to 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 
    ... 
    

    【讨论】:

    猜你喜欢
    • 2010-10-30
    • 1970-01-01
    • 2013-08-28
    • 2015-05-18
    • 2023-04-05
    • 2015-08-14
    • 2011-07-14
    • 2015-01-24
    相关资源
    最近更新 更多