簡體   English   中英

如何使用LINQ to XML連接具有相同名稱值的所有子元素

[英]How to concatenate all child elements with same names values using LINQ to XML

說XML文件如下所示:

<root>
  <book>
    <title>book1Title</title>
    <author>book1Author1</author>
  </book>
  <book>
    <title>book2Title</title>
    <author>book2Author1</author>
    <author>book2Author2</author>
  </book>
  ...
  <book>
    <title>book9Title1</title>
    <title>book9Title2</title>
    <author>book9Author</author>
  </book>
</root>

我需要的輸出如下:

<root>
  <book>
    <title>book1Title</title>
    <author>book1Author1</author>
  </book>
  <book>
    <title>book2Title</title>
    <author>book2Author1, book2Author2</author>
  </book>
  ...
  <book>
    <title>book9Title1, book9Title2</title>
    <author>book9Author</author>
  </book>
</root>

我的想法是使用嵌套的foreach:

foreach(var book in doc1.Root.Elements("book"))  //doc1 is XDocument
  {
    foreach (var datafield in book)
      {
        //select all XElements with name datafield.Name
        //put all the values to list
        //delete all selected XElements
        //create new XElement with name datafield.Name and write text values from list to it
      }
  }

但我不能這樣做,因為:

“foreach語句不能對'System.Xml.Linq.XElement'類型的變量進行操作,因為'System.Xml.Linq.XElement'不包含'GetEnumerator'的公共定義”

即使var book是一個具有其他元素的元素,與XElement Iteration中的情況不同,並將其添加到父問題中。

你可以這樣做:

foreach(var book in doc1.Root.Elements("book"))
{
   var authors=String.Join(",",book.Elements("author").Select(e=>e.Value));// get all authors and create the result that you need
   book.Elements("author").Remove();// remove all authors from current book
   book.Add(new XElement("author", authors)); // create one node with all the author's names

   //Do the same with the titles
   var titles=String.Join(",",book.Elements("title").Select(e=>e.Value));
   book.Elements("title").Remove();
   book.Add(new XElement("title", titles));
}

聽起來像xslt的工作

using System;
using System.Xml;
using System.Xml.Xsl;
using System.IO;

public class Program
{
    public static void Main()
    {
        var xsl = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xsl:stylesheet version=""1.0""
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">

<xsl:template match=""/"">
  <root>
    <xsl:for-each select=""root/book"">
        <book>
        <author>
        <xsl:for-each select=""author"">
          <xsl:value-of select=""current()""/>
          <xsl:if test=""last() > position()"">
            <xsl:text>, </xsl:text>
          </xsl:if>
        </xsl:for-each>
        </author>
        <title>
          <xsl:for-each select=""title"">
          <xsl:value-of select=""current()""/>
          <xsl:if test=""last() > position()"">
            <xsl:text>, </xsl:text>
          </xsl:if>
        </xsl:for-each>
        </title>
      </book>
    </xsl:for-each>
  </root>
</xsl:template>
</xsl:stylesheet>";

        var xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
        <root>
  <book>
    <title>book1Title</title>
    <author>book1Author1</author>
  </book>
  <book>
    <title>book2Title</title>
    <author>book2Author1</author>
    <author>book2Author2</author>
  </book>
  <book>
    <title>book9Title1</title>
    <title>book9Title2</title>
    <author>book9Author</author>
  </book>
</root>";

        string output = String.Empty;
        using (StringReader srt = new StringReader(xsl)) // xslInput is a string that contains xsl
        using (StringReader sri = new StringReader(xml)) // xmlInput is a string that contains xml
        {
            using (XmlReader xrt = XmlReader.Create(srt))
            using (XmlReader xri = XmlReader.Create(sri))
            {
                var xslt = new XslCompiledTransform();
                xslt.Load(xrt);
                using (StringWriter sw = new StringWriter())
                using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
                {
                    xslt.Transform(xri, xwo);
                    output = sw.ToString();
                }
            }
        }
        Console.WriteLine(output);
    }
}

這個XML不會更好地工作....

<root>
    <book>
         <title>book1Title</title>
         <authors>
              <author>book1Author1</author>
         </authors>
     </book>
     <book>
          <title>book2Title</title>
          <authors>
               <author>book2Author1</author>
               <author>book2Author2</author>
          </authors>
     </book>
</root>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM