用另一个 XElement 包装 XElement

Wrap XElement with another XElement

我有一个 XElements 集合,我得到了 doc.Root.Element("Doc").Elements("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 >
      <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>

你不是那样做的。使用 System.Linq.Xml.

时,切勿直接操作 XML

我脑海中的算法:

  • 创建列表 elementsToDelete

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

  • 循环后,对 elementsToDelete 执行新循环并从项目的父元素中删除它包含的所有元素

代码中应该是这样的:

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));
}

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

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