【问题标题】:How to use xpath in Linq to check elements and attributes如何在 Linq 中使用 xpath 来检查元素和属性
【发布时间】:2015-08-09 08:25:07
【问题描述】:

我正在尝试连接两个 XML 文件,连接键有时作为元素出现,但有时作为属性出现,如下面的 XML 文件所示。如何使用 XPath 或 ||运营商解决问题?任何其他解决方案也非常感谢。提前谢谢了!

文件一:

<bookstore>
   <book>
     <bookID>100</bookID>
     <name> The cat in the hat </name>
   </book>
   <book>
     <bookID>90</bookID>
     <name> another book </name>
   </book>
   <book>
     <bookID>103</bookID>
     <name> a new book </name>
   </book>
</bookstore>

文件二,这里的join key bookID是属性:

 <bookstore>
  <book bookID=100>
    <content> story </content>
  </book>
  <book bookID=90>
    <content> fiction </content>
  </book>
  <book bookID=103>
    <content> bio </content>
  </book>

我想要的结果是

<result>
<bookInfo>
   <bookID>103</bookID>
   <name> a new book </name>
   <content> bio </content>
<bookInfo>
</result>

我目前基于这个问题的join操作Compare elements from two xml documents based on element value in C#

    var bookInfos =
          from a in fileone.Descendants("book")
          join b in filetwo.Descendants("book")
              on (string)a.Element("bookID") equals  (string)b.Element("bookID") //how can I change the Join condition as the key might attributes in any of the two files? 
    select new XElement("bookInfo", 
                            a.Element("bookID"), 
                            a.Element("name"), 
                            b.Element("content")
                        );

【问题讨论】:

    标签: c# xml linq join xpath


    【解决方案1】:

    您可以使用null coalescing operator ?? 首先检查是否存在名为"bookID" 的属性,如果不存在,则检查该名称的元素:

            var bookInfos =
                  from a in fileone.Descendants("book")
                  join b in filetwo.Descendants("book")
                      on ((string)a.Attribute("bookID") ?? (string)a.Element("bookID")) equals ((string)b.Attribute("bookID") ?? (string)b.Element("bookID"))
                  select new XElement("bookInfo",
                                          new XElement("bookID", (string)a.Attribute("bookID") ?? (string)a.Element("bookID")),
                                          a.Element("name"),
                                          b.Element("content")
                                      );
    

    【讨论】:

      【解决方案2】:

      您可以在连接条件中表达您检索元素或属性的逻辑:

      var bookInfos =
          from a in fileone.Descendants("book")
          let aBookID = (string)a.Element("bookID") ?? (string)a.Attribute("bookID")
          join b in filetwo.Descendants("book")
              on aBookID equals (string)b.Element("bookID") ?? (string)b.Attribute("bookID")
          select new XElement("bookInfo",
              aBookID,
              a.Element("name"),
              b.Element("content")
          );
      

      【讨论】:

        【解决方案3】:

        试试这个

        on (string)a.Element("bookID") equals (string)(b.Attribute("bookID")) 
        

        fiddle

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-07
          • 1970-01-01
          • 2014-05-14
          相关资源
          最近更新 更多