用另一个XElement包装XElement

时间:2017-06-19 07:26:39

标签: c# linq-to-xml

我有一些XElements,我得到doc.Root.Element("Doc").Elements("PersonalData")

Collection看起来像这样:

<PersonalData att1="0" att2="21" att3="2017">
        <element1>
          <data name="test test test" />
        </element1>
        <element2>
          <element3 att1="66725.67" att2="51769.82" >
            <data att1="03" att2="HP"/>
            <data att1="03" att2="HP"/>
            <data att1="03" att2="HP"/>
          </element3>
        </element2>
</PersonalData >
      <PersonalData att1="0" att2="21" att3="2017">
        <element1>
          <data name="test test test" />
        </element1>
        <element2>
          <element3 att1="66725.67" att2="51769.82" >
            <data att1="03" att2="HP"/>
            <data att1="03" att2="HP"/>
            <data att1="03" att2="HP"/>
          </element3>
        </element2>
</PersonalData >

我想用<row>元素围绕集合中的每个元素。

我试过这样做:

foreach (var item in doc.Root.Element("Doc").Elements("PersonalData"))
            {
               item.AddBeforeSelf("<row>");
               item.AddAfterSelf("</row>");
            }

但除了"<"我得到&lt &gt。 我可以以某种方式修复它,还是可以执行以下操作:

item.ReplaceWith(new XElement("row").Add(item)); 

我该怎么做呢?

最后应该看起来像:

<row>
<PersonalData att1="0" att2="21" att3="2017">
            <element1>
              <data name="test test test" />
            </element1>
            <element2>
              <element3 att1="66725.67" att2="51769.82" >
                <data att1="03" att2="HP"/>
                <data att1="03" att2="HP"/>
                <data att1="03" att2="HP"/>
              </element3>
            </element2>
    </PersonalData >
</row>
<row>
<PersonalData att1="0" att2="21" att3="2017">
            <element1>
              <data name="test test test" />
            </element1>
            <element2>
              <element3 att1="66725.67" att2="51769.82" >
                <data att1="03" att2="HP"/>
                <data att1="03" att2="HP"/>
                <data att1="03" att2="HP"/>
              </element3>
            </element2>
    </PersonalData >
</row>

2 个答案:

答案 0 :(得分:1)

那不是你怎么做的。使用System.Linq.Xml时,不应直接操作XML。

我头脑中的算法:

  • 创建List elementsToDelete

  • 在循环中,将每个项目添加到此列表中,并将新的XElement(项目)添加到项目的父元素

  • 循环之后,在elementsToDelete上执行一个新循环,并从项目中删除它包含的所有元素&#39;父元素

这应该是代码:

var elementsToDelete = new List<XElement>();
var parentElement = doc.Root.Element("Doc");
foreach (var item in parentElement.Elements("PersonalData"))
{
    elementsToDelete.Add(item);
}

foreach (var element in elementsToDelete)
{
    element.Remove();
    parentElement.Add(new XElement("row", element));
}

答案 1 :(得分:1)

可以使用ReplaceWith(),你只需要预先收集要替换的元素,因为在你主动修改它时你无法枚举文档的元素。将它们放入列表通常就足够了。

foreach (var pd in doc.Descendants("PersonalData").ToList())
    pd.ReplaceWith(new XElement("row", pd));