3

これは私のxmlです。

<Document>
<page no="1">
  <Paragraph no="1">
    <Line>line1</Line>
  </Paragraph>
  <Paragraph no="2">
    <Line>line2</Line>
  </Paragraph>
</page>
<page no="2">
  <Paragraph no="1">
    <Line>line1</Line>
  </Paragraph>
  <Paragraph no="2">
    <Line>line2</Line>
  </Paragraph>
</page>
</Document>

私のC#コードは

XmlDocument xd = new XmlDocument();
            xd.Load(@"H:\Sample-8-final.xml");
            XmlNodeList pnodelist = xd.GetElementsByTagName("page");
            XmlNodeList xdChildNodeList = xd.ChildNodes;

            for (int i = 0; i < pnodelist.Count; i++)
            {
                XmlNode pageNode = pnodelist[i];
                foreach (XmlNode xxNode in pageNode.ChildNodes)
                {
                    if (xxNode.Name.ToString().Trim().Equals("Paragraph"))
                    {
                        foreach (XmlNode yyNode in xxNode.ChildNodes)
                        {
                            yyNode.ParentNode.RemoveChild(yyNode);
                        }
                    }
                }
                xd.Save(@"H:\Sample-8-final_1.xml");

私の必要な出力は

<Document>
<page no="1">
  <Paragraph no="1">
  </Paragraph>
  <Paragraph no="2">
  </Paragraph>
</page>
<page no="2">
  <Paragraph no="1">
  </Paragraph>
  <Paragraph no="2">
  </Paragraph>
</page>
</Document>

しかし、私のコードは以下のような間違った結果を生成しました:

<Document>
    <page no="1">
      <Paragraph no="1">
      </Paragraph>
      <Paragraph no="2">
        <Line>line2</Line>
      </Paragraph>
    </page>
    <page no="2">
      <Paragraph no="1">
      </Paragraph>
      <Paragraph no="2">
        <Line>line2</Line>
      </Paragraph>
    </page>
    </Document>

この問題から抜け出すために私を導いてください...

4

5 に答える 5

11

LINQ to XMLを使用して、段落要素のすべての子孫を削除します。

XElement root = XElement.Load(@"H:\Sample-8-final_1.xml");
root.Descendants("Paragraph").Descendants().Remove();

using System.Xml.Linq;注:ファイルの先頭に配置する必要があります。

于 2012-09-06T10:34:39.980 に答える
3

問題は、次の行で繰り返し処理しているものを変更していることです。

foreach (XmlNode yyNode in xxNode.ChildNodes)
{
    yyNode.ParentNode.RemoveChild(yyNode);
}

これは、に置き換える場合に簡単に見つけることができますyyNode.ParentNodexxNodeこれは確実にそうなります)。これにより、イテレータが混乱し、不要なものをスキップする原因になります。

を呼び出すだけですが、おそらく簡単ですxxNode.RemoveAll()。ドキュメントを参照してください:http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.removeall

ただし、Mahenが言うように、これにより属性も削除されるため、多くの場合、望ましい解決策ではないことに注意してください(この場合はたとえばそうではありません)。

于 2012-09-06T10:34:55.683 に答える
3

ChrisはChildNodes、コレクションを反復処理しているときに(削除して)変更しているため、反復が失敗することを説明しました。彼はRemoveAll()代わりに使用することを提案した。しかしRemoveAll()、子要素だけでなく属性も削除します。これは私が望んでいることではありません。したがって、これは、属性を保持しながら(VB.NETで)安全に反復するために私が書いたものです。

Private Shared Sub RemoveAllChildren(element As XmlElement)
    ' you can't iterate and delete in the same loop, because you would be modifying .ChildNodes
    Dim childrenList = New ArrayList()
    For Each child In element.ChildNodes
        childrenList.Add(child)
    Next
    For Each child In childrenList
        child.ParentNode.RemoveChild(child)
    Next
End Sub
于 2013-05-10T21:26:50.313 に答える
2

コードに問題はありません。リテラルと正確に一致する必要があります。大文字と小文字が区別されます。「PAGE」の代わりに「page」を、「PARAGRAPH」の代わりに「Paragraph」と書くと、コードは問題なく機能します。

于 2012-09-06T10:37:35.607 に答える
0
while (parentNode.ChildNodes.Count > 0) 
{
   parentNode.RemoveChild(parentNode.ChildNodes[0]);
}

また動作するはずです。

于 2022-01-29T04:12:27.663 に答える