使用LINQ选择XML中的特定节点 [英] Select specific nodes in XML with LINQ

查看:178
本文介绍了使用LINQ选择XML中的特定节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个函数来加载和XML文档并将其转换为CSV。因为我只需要一些XML文件中的值,我想实现的目标是只选择我感兴趣的节点。



这里是我的代码:

  XDocument csvDocument = XDocument.Load(tempOutput); 

StringBuilder csvBuilder = new StringBuilder(1000);

foreach(csvDocument.Descendants(Sample)中的XElement节点)
{
foreach(nodeElements()中的XElement innerNode)
{
csvBuilder.AppendFormat({0},innerNode.Value);
}

csvBuilder.Remove(csvBuilder.Length-1,1);

csvBuilder.AppendLine();
}
csvOut = csvBuilder.ToString();

但是,这样我就选择了Sample节点内的所有子节点。 / p>

在XML中,Sample树是:

  Sample Type =ObjectClass =Sample> 
< ID> 1< / ID>
< Name> 10096< / Name>
< Type> 2< / Type>
< Rep> 0< / Rep>
< Selected> True< / Selected>
< Position> 1< / Position>
< Pattern> 0< / Pattern>
< / Sample>

代码工作正常,但我只需要选择ID和Selected



感谢。



/ p>

解决方案

进一步了解 Linq-to-xml这里。您不是真正利用 XObject s

的'linq-edness'

  var samples = csvDocument.Descendants(Sample)
.Select(el => new {
Id = el.Element(ID)。 Value,
Selected = el.Elemnt(Selected)。Value
});

这会为您创建一个 IEnumerable< T> 'T' Id 和已选择的属性>匿名类型
您可以解析( int.Parse bool.Parse )类型安全的Id和选定值。但由于你只是写一个 StringBuilder 对象,你可能不在乎...只是一个FYI。



StringBuilder对象可以写成如下:

  foreach(var sample in samples){
csvBuilder.AppendFormat(myFormattedString ,sample.Id,sample.Selected);
}

注意,你的匿名对象和 for-each 循环应在同一范围内。但是有必要的方法。



像往常一样,有一种方法可以让一只猫皮肤。



在参考中

更新 ...。

  foreach(csvDocument.Descendants(Sample)中的XElement节点)
{
foreach(XElement innerNode in node.Elements())
{
//此逻辑假定值的不同格式化
//否则,将if语句更改为||每个比较
if(innerNode.Name ==ID){
// append / format stringBuilder
continue;
}

if(innerNode.Name ==Selected){
// append / format stringBuilder
continue;
}
}

csvBuilder.Remove(csvBuilder.Length -1,1);

csvBuilder.AppendLine();
}


I'm writing a function that loads and XML document and converts it to a CSV. Since I need only some values from the XML file, the goal i'm trying to achieve is to select only the nodes I'm interested in.

Here's my code:

      XDocument csvDocument = XDocument.Load(tempOutput);

        StringBuilder csvBuilder = new StringBuilder(1000);

        foreach (XElement node in csvDocument.Descendants("Sample"))
        {
            foreach (XElement innerNode in node.Elements())
            {
                        csvBuilder.AppendFormat("{0},", innerNode.Value);
                    }

                    csvBuilder.Remove(csvBuilder.Length -1, 1);

                    csvBuilder.AppendLine();
                }
                csvOut = csvBuilder.ToString();

But, in this way I'm selectin ALL the child nodes inside the "Sample" node.

In the XML, "Sample" tree is:

<Sample Type="Object" Class ="Sample">
    <ID>1</ID>
    <Name>10096</Name>
    <Type>2</Type>
    <Rep>0</Rep>
    <Selected>True</Selected>
    <Position>1</Position>
    <Pattern>0</Pattern>
   </Sample>

Code works flawlessly, but I need only "ID" and "Selected" to be selected and their values written inside the CSV file.

Could anyone point me in the right direction, please?

Thanks.

解决方案

Learn more about Linq-to-xml here. You're not really taking advantage of the 'linq-edness' of XObjects

var samples = csvDocument.Descendants("Sample")
                         .Select(el => new {
                             Id = el.Element("ID").Value,
                             Selected = el.Elemnt("Selected").Value
                         });

This creates for you an IEnumerable<T> where 'T' is an anonymous type with the properties Id and Selected. You can parse (int.Parse or bool.Parse) the Id and Selected values for type safety. But since you are simply writing to a StringBuilder object you may not care ...just an FYI.

The StringBuilder object can then be written as follows:

foreach (var sample in samples) {
    csvBuilder.AppendFormat(myFormattedString, sample.Id, sample.Selected);
}

The caveat to this is that your anonymous object and the for-each loop should be within the same scope. But there are ways around that if necessary.

As always, there is more than one way to skin a cat.

Update ...in ref. to comment:

foreach (XElement node in csvDocument.Descendants("Sample"))
{
    foreach (XElement innerNode in node.Elements())
    {
        //    this logic assumes different formatting for values
        //    otherwise, change if statement to || each comparison
        if(innerNode.Name == "ID") {
            // append/format stringBuilder
            continue;
        }

        if(innerNode.Name == "Selected") {
            // append/format stringBuilder
            continue;
        }
    }

    csvBuilder.Remove(csvBuilder.Length -1, 1);

    csvBuilder.AppendLine();
}

这篇关于使用LINQ选择XML中的特定节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆