XML到LINQ如何获取确切的信息?

时间:2015-03-24 22:37:38

标签: c# xml linq

我想从下面的xml示例中提取一些信息。我想提取一个包含我感兴趣的列的行集合。

我真的不知道该怎么做...我试过这段代码,但它没有用:

    XElement elem = XElement.Load("SIMC.xml");
    var homePhone = from phoneno in elem.Elements("row")
                    where (string)phoneno.Element("col").Attribute("name") == "NAZWA"
                    select phoneno;
   // Console.WriteLine("List HomePhone Nos.");
    foreach (XElement xEle in homePhone)
    {
        MessageBox.Show(xEle.Element("col").Value);
    }

以下是我正在尝试解析的XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<teryt>
<catalog name="SIMC" type="all" date="2015-01-01">
<row>
<col name="WOJ">18</col>
<col name="POW">16</col>
<col name="GMI">13</col>
<col name="RODZ_GMI">2</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Na Polu</col>
<col name="SYM">0664326</col>
<col name="SYMPOD">0664310</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">28</col>
<col name="POW">06</col>
<col name="GMI">05</col>
<col name="RODZ_GMI">2</col>
<col name="RM">03</col>
<col name="MZ">1</col>
<col name="NAZWA">Majerka</col>
<col name="SYM">0761615</col>
<col name="SYMPOD">0761609</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">12</col>
<col name="POW">09</col>
<col name="GMI">03</col>
<col name="RODZ_GMI">5</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Pod Kamiennikiem</col>
<col name="SYM">0328485</col>
<col name="SYMPOD">0328456</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">32</col>
<col name="POW">17</col>
<col name="GMI">04</col>
<col name="RODZ_GMI">5</col>
<col name="RM">01</col>
<col name="MZ">1</col>
<col name="NAZWA">Miłogoszcz</col>
<col name="SYM">0530732</col>
<col name="SYMPOD">0530732</col>
<col name="STAN_NA">2015-01-01</col>
</row>

我想提取行元素,其中列的属性name等于NAZWA,列值为Miłogoszcz

我的代码暂时没有显示

2 个答案:

答案 0 :(得分:1)

您需要使用Descendents或正确地遍历XML层次结构,您正在跳过逻辑中的两个级别。我还将(string)更改为.Value以使其正常工作。

XElement elem = XElement.Load("SIMC.xml");
var homePhone = from phoneno in elem.Elements("teryt")
                                    .Elements("catalog")
                                    .Elements("row")
                where phoneno.Elements("col")
                             .Any(xelm =>
                                      xelm.Attribute("name").Value == "NAZWA" &&
                                      xelm.Value == "Miłogoszcz")
                select phoneno;
// Console.WriteLine("List HomePhone Nos.");
foreach (XElement xEle in homePhone)
{
    //Note that you need to decide how to format this
    MessageBox.Show(string.Join(", ",
                    xEle.Select(x => x.Attribute("name").Value + "=" + x.Value));
}

答案 1 :(得分:0)

如果我们直观地思考这个问题,我们真正想要的是:

  

返回该行中有任何列的行,该行具有属性&#39; name&#39;具有特定值和具有特定值的列值。

假设我们已经获得了代表XML文件的行元素的IEnumerable<XElement> rows。然后,我们可以使用LINQ的扩展方法仅选择我们关心的行。这是一个这样的功能可能是什么样的。

    public static IEnumerable<XElement> GetRowsWithColumn(IEnumerable<XElement> rows, String name, String value) 
    {
        return rows
            .Where(row => row.Elements("col") //Get Columns
                .Any(col => //This column should...
                    col.Attributes("name").Any(attr => attr.Value.Equals(name)) //have the right name attribute
                    && col.Value.Equals(value))); //and have the right value
    }

这是一个完整的程序,我相信你做的是你所要求的。它打开文件然后探索元素,返回有子元素的行&#34; col&#34;其属性名称的值为NAZWA,该列的值为Miłogoszcz

此代码使用我们上面编写的函数,因此您可以为列名属性和列的值插入任何您喜欢的内容。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace StackOverflowTest
{
    class Program
    {
        public static IEnumerable<XElement> GetRowsWithColumn(IEnumerable<XElement> rows, String name, String value) 
        {
            return rows
                .Where(row => row.Elements("col")
                    .Any(col =>
                        col.Attributes("name").Any(attr => attr.Value.Equals(name))
                        && col.Value.Equals(value)));
        }
        static void Main(string[] args)
        {
            //Load file
            XElement elem = XElement.Load("./test.xml");

            //Get Rows
            var rows = elem
                .Elements("catalog")
                .Elements("row");

            //Filter rows
            var interestingRows = GetRowsWithColumn(rows, "NAZWA", "Miłogoszcz");

            //Print rows
            foreach (var row in interestingRows)
            {
                //This is MessageBox.Show in your example
                Console.WriteLine(row);
            }

            Console.Read();
        }
    }
}

我希望能解决你的问题。如果我错过任何事情,请告诉我。

请注意,我确实通过包含顶级元素的结束块来更改您的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<teryt>
<catalog name="SIMC" type="all" date="2015-01-01">
<row>
<col name="WOJ">18</col>
<col name="POW">16</col>
<col name="GMI">13</col>
<col name="RODZ_GMI">2</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Na Polu</col>
<col name="SYM">0664326</col>
<col name="SYMPOD">0664310</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">28</col>
<col name="POW">06</col>
<col name="GMI">05</col>
<col name="RODZ_GMI">2</col>
<col name="RM">03</col>
<col name="MZ">1</col>
<col name="NAZWA">Majerka</col>
<col name="SYM">0761615</col>
<col name="SYMPOD">0761609</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">12</col>
<col name="POW">09</col>
<col name="GMI">03</col>
<col name="RODZ_GMI">5</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Pod Kamiennikiem</col>
<col name="SYM">0328485</col>
<col name="SYMPOD">0328456</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">32</col>
<col name="POW">17</col>
<col name="GMI">04</col>
<col name="RODZ_GMI">5</col>
<col name="RM">01</col>
<col name="MZ">1</col>
<col name="NAZWA">Miłogoszcz</col>
<col name="SYM">0530732</col>
<col name="SYMPOD">0530732</col>
<col name="STAN_NA">2015-01-01</col>
</row>
</catalog>
</teryt>