1

次のxmlを検討してください。

<div>
   <a href="http://www.google.com/">This is:</a>
   <p>A test... <b>1</b><i>2</i><u>3</u></p>
   <p>This too</p>
   Finished.
</div>

このxmlのコンテンツはSystem.Xml.XmlDocumentインスタンスにあります。すべての要素を置き換えてp、各段落要素の後にブレークを追加する必要があります。私は次のコードを書きました:

var pElement = xmlDocument.SelectSingleNode("//p");
while (pElement != null)
{
    var textNode = xmlDocument.CreateTextNode("");
    foreach (XmlNode child in pElement.ChildNodes)
    {
        textNode.AppendChild(child);
    }    
    textNode.AppendChild(xmlDocument.CreateElement("br"));
    pElement.ParentNode.ReplaceChild(pElement, textNode);
    pElement = xmlDocument.SelectSingleNode("//p");
}

空のノードを作成し、それに各段落ノードの子ノードを追加しています。残念ながら、これは機能しません。テキストノードに要素を含めることはできません。

この置換を実装する方法はありますか?

4

3 に答える 3

2

InsertAfter次の方法を使用して解決策を見つけたようです。

var pElement = xmlDocument.SelectSingleNode("//p");

while (pElement != null)
{    
    //store position where new elements need to be added
    var position = pElement;

    while(pElement.FirstChild != null)
    {
        var child = pElement.FirstChild;
        position.ParentNode.InsertAfter(child, position);

        //store the added child as position for next child
        position = child;
    }

    //add break
    position.ParentNode.InsertAfter(xmlDocument.CreateElement("br"), position);

    //remove empty p
    pElement.ParentNode.RemoveChild(pElement);

    //select next p
    pElement = xmlDocument.SelectSingleNode("//p");
}

アイデアは次のとおりです。

  1. すべてのpノードを調べます。
  2. のすべての子ノードをループしますp
  3. それらを正しい位置に追加します。
  4. p各ノードの後に​​ブレークを追加します。
  5. 要素を削除しpます。

位置を見つけるのはかなりトリッキーでした。最初の子ノードは、位置要素としてwithpを使用して、の親ノードに追加する必要があります。ただし、前に追加した子の後に次の子を追加する必要があります。解決策:その位置を保存して使用します。InsertAfterp

注:ノードの半分を移動した後、イテレーターはそれが完了したと判断するためfor each、コレクションでイテレーターを使用するpElement.ChildNodesことはできません。オブジェクトのコレクションではなく、ある種のカウントを使用しているようです。

于 2013-02-25T18:30:04.140 に答える
0

メモリ内のオブジェクトの変更XmlDocumentには問題があります。同様の問題をここで参照してください。

最も簡単な方法は、XSLTを使用することです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="p">
    <xsl:copy-of select="node()"/>
    <br/>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

次に、出力XMLで文字列またはストリームを生成XmlDocumentするクラスを使用してそれを適用できます。XslCompiledTransform

于 2013-02-25T16:29:28.067 に答える
0

あなたが達成しようとしていることを私が理解した場合、あなたは次のようなことを試みることができます:

foreach (XmlNode node in doc.SelectNodes("//p"))
{
    node.ParentNode.InsertAfter(doc.CreateElement("br"), node);
}

私が正しく理解していない場合は、達成しようとしている出力を投稿することができます。

于 2013-02-25T16:35:40.440 に答える