简体   繁体   English

Linq to xml带有过滤器的扩展方法

[英]Linq to xml extension method with filter

I have the following XML file: 我有以下XML文件:

<GSP>
    <RES>
    <R N="1">
          <FS NAME="date" VALUE="2013-08-26"/>
          <MT N="Title" V="article title"/>
          <MT N="UrlTitle" V="article url title"/>
          <MT N="Description" V="Lorem ipsum dolor sit amet, consectetur adipisicing elit, deserunt mollit anim id est laborum."/>
          <MT N="IsSpecialArticle" V="true"/>
    </R>
    <R N="2">
          <FS NAME="date" VALUE="2013-08-20"/>
          <MT N="Title" V="article title 2"/>
          <MT N="UrlTitle" V="article url title 2"/>
          <MT N="Description" V="Lorem ipsum dolor sit amet, consectetur adipisicing elit, deserunt mollit anim id est laborum. 2"/>
          <MT N="IsSpecialArticle" V="false"/>
    </R>
   <R N="3">
          <FS NAME="date" VALUE="2013-08-20"/>
          <MT N="Title" V="article title 3"/>
          <MT N="UrlTitle" V="article url title 3"/>
          <MT N="Description" V="Lorem ipsum dolor sit amet, consectetur adipisicing elit, deserunt mollit anim id est laborum. 3"/>
          <MT N="IsSpecialArticle" V="true"/>
    </R>
    </RES>
</GSP>

The following code to load into a XElement an xml document: 以下代码将xml文档加载到XElement中:

XElement xElement = XElement.Load(Server.MapPath("~/Xml/samplexml.xml"));

My issue is the following, i dont know how to configure the following sentence in order to get those items that have a "true" on the V attribute, on the element MT where N="IsSpecialArticle". 我的问题是以下内容,我不知道如何配置以下语句以使元素MT上的N =“ IsSpecialArticle”的V属性具有“ true”的那些项。

xElement.Element("RES").Elements("R").Select(??????).Where(???);

Do you know how i could archieve this? 你知道我怎么归档吗?

Thanks a lot in advance. 非常感谢。

Best regards. 最好的祝福。

jose. 乔斯。

First of all, I would load your XML into XDocument instead of XElement : 首先,我将XML而不是XElement加载到XDocument中:

var doc = XDocument.Load(Server.MapPath("~/Xml/samplexml.xml"));

And the query: 和查询:

var specialItems = from r in doc.Root.Elements("RES").Elements("R")
                   let mt = r.Elements("MT").FirstOrDefault(x => (string)x.Attribute("N") == "IsSpecialArticle")
                   let isTrue = mt != null && (bool)mt.Attribute("V")
                   where isTrue
                   select r;
xElement
.Element("RES")
.Elements("R")
.Where
(
    x=>
    x
    .Elements("MT")
    .Where
    (
        z=>
        z.Attribute("N").Value == "IsSpecialArticle"
    )
    .Select
    (
        z=>
        z.Attribute("V").Value
    ).SingleOrDefault() == "true"
)

Something like this: 像这样:

var res = (from p in xElement.Element("RES").Elements("R")
           where p.Elements("MT").Any(q => 
                 (string)q.Attribute("N") == "IsSpecialArticle" && 
                 (bool)q.Attribute("V") == true)
           select p).ToArray();

We use the Any() operator to look "inside" the R element and then the various explicit casts of XAttribute to convert the attribute values to .NET types. 我们使用Any()运算符在R元素中“查找”,然后使用XAttribute的各种显式强制转换将属性值转换为.NET类型。

Note that (bool)q.Attribute("V") == true is "too much" :-) (bool)q.Attribute("V") would be enough, but I think that in this particular situation, the == true makes the expression more readable. 请注意, (bool)q.Attribute("V") == true是“太多” (bool)q.Attribute("V")就足够了,但是我认为在这种特殊情况下, == true使表达式更具可读性。

If V is optional, you can 如果V是可选的,则可以

                 (bool?)q.Attribute("V") == true)

note that in this case the == true is necessary. 请注意,在这种情况下, == true是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM