解析XElement

3
我是一名初学LINQ/XML的新手。我刚学会了可以使用语言集成查询来解析xml。我正在尝试解析以下XML结构,需要帮助。

==================================

<config>

<params>
  <tp name="abc">yes</tp>
  <tp name="aee">no</tp>
  <tp name="bbc">no</tp>
  <tp name="ccb">yes</tp>
</params>

<nits>
  <tn name="kjh">
    <min>44</min>
    <max>98</max> 
  </tn>

  <tn name="klm">
    <min>55</min>
    <max>88</max> 
  </tn>

  <tn name="hhh">
    <min>44</min>
    <max>98</max> 
  </tn>
</nits>

<params>
  <tp name="lml">no</tp>
  <tp name="rre">yes</tp>
  <tp name="rst">no</tp>
  <tp name="wee">yes</tp>
</params>

<nits>
  <tn name="adf">
    <min>44</min>
    <max>98</max> 
  </tn>

  <tn name="ddd">
    <min>42</min>
    <max>92</max> 
  </tn>

  <tn name="kjj">
    <min>92</min>
    <max>98</max> 
  </tn>
</nits>

</config>

==================================

需要输出:

我的目标是将上述数据按类别显示为键值对,可以在文本文件或数据网格中进行。

<Params>
abc : yes
aee : no
bbc : yes
...
...
...
...


<nits>

kjh: 44 , 98
klm: 55 , 88
...
...
kjj: 92 , 98
ddd: 42 , 92
...

目前我编写的代码如下:

static void QueryTheData(XDocument doc)
        {
            try
            {
                var a = doc.Descendants("config").Elements("params");
                var b = doc.Descendants("config").Elements("nits");

                var c = doc.Elements("tp");
                var d = doc.Elements("tn");

               /* to do :  parse the elements into key value pairs */
               /* Need hint or help to proceed to get key value pairs from xml data

            }
             catch(Exception e)
            {
                 ....
            }               
 }

有关LINQ/XML C#初学者的好建议也是需要的。

谢谢提前, ak


似乎这是XSLT的绝佳工作。 - sehe
4个回答

2
我想到了这个:
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using System.IO;
using System;

public class Program
{
    public static void Main(string[] args)
    {
        using (var fs = new StreamReader("./test.xml"))
        {
            var doc = XDocument.Load(fs);

            var parms = doc.Root.XPathSelectElements("params/tp")
                .ToDictionary(el => el.Attribute("name").Value, el => el.Value);

            var nits = doc.Root.XPathSelectElements("nits/tn")
                .Select(el => new {
                        Name = el.Attribute("name").Value,
                        Min  = (int) el.Element("min"),
                        Max  = (int) el.Element("max")
                    }).ToList();

            foreach (var kvp in parms)
                Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value);

            foreach (var nit in nits
                    .OrderBy(nit => nit.Name)
                    .ThenBy(nit => nit.Max))
            {
                Console.WriteLine("{0}: {1} {2}", nit.Name, nit.Min, nit.Max);
            }
        }
    }
}

这显示了一些成分,包括在集合类型中存储params/nits的不同方法。输出:
abc: yes
aee: no
bbc: no
ccb: yes
lml: no
rre: yes
rst: no
wee: yes
adf: 44 98
ddd: 42 92
hhh: 44 98
kjh: 44 98
kjj: 92 98
klm: 55 88

输出似乎正是医生开的药方。 - sehe

1

所以你想从每个<tp>元素中获取name属性和文本值?这很容易:

// Parameters
var query = doc.Descendants("tp")
               .Select(tp => new { Name = tp.Attribute("name").Value,
                                   Value = tp.Value });

foreach (var result in query)
{
    Console.WriteLine("{0} : {1}", result.Name, result.Value);
}

对于最小/最大部分同样如此:

var query = doc.Descendants("tn")
               .Select(tn => new { Name = tn.Attribute("name").Value,
                                   Min = (int) tn.Element("min"),
                                   Max = (int) tn.Element("max") });

foreach (var result in query)
{
    Console.WriteLine("{0}: {1}, {2}", result.Name, result.Min, result.Max);
}

当然,这假设XML遵循您所制定的模式 - 如果元素没有正确的子元素或属性,则会失败。


哦,太好了。我不知道XElement上有转换运算符 :) +1 - sehe

1

绝对不行 - XmlReader 会比使用 LINQ to XML 更加困难。 - Jon Skeet
@JonSkeet 这就是为什么答案包括LINQ to XML和XmlReader的原因。 - Chimera
现在你举了一个例子,很明显是关于一段与 OP 的示例无关的 XML 代码,并且没有使用你一开始提到的 XmlReaderStringBuilder - Jon Skeet
答案并不包括它。它包括链接,其中之一讨论了LINQ to XML,但没有给出任何具体指导。抱歉,这不是一个好的答案。 - Jon Skeet
@JonSkeet 楼主说:“有没有关于初学者LINQ/XML C#的好建议?”我相信我提供了这些信息,并且还提供了一个可以适应楼主XML的示例。 - Chimera
至少你应该提供更好的链接文本 - 鉴于它在一个以“有关如何做到这一点”的句子开头,任何人都会期望它是关于XmlReaderStringBuilder的。至于调整你的代码... 我看到很少与OP相关的内容。发布一个只与问题有些牵强附会的大量代码没有什么意义。 - Jon Skeet

0

Jon Skeet的答案将帮助您选择输出中的参数部分。

有没有适合初学者使用的LINQ/XML C#的好指南?

我推荐Jon Skeet的C# in Depth, Second Edition。这是一个很棒的C#书籍,包括一些关于LINQ to XML的内容。在您等待书籍到达的同时,作为书籍的补充,我推荐Microsoft的LINQ to XML文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接