dom4j:在文本内容中添加PI

时间:2015-12-16 08:03:34

标签: java dom4j

我有以下元素:

<text>
text and text and text
<stop/>
text and text and text
<stop/>
text and text and text
<stop/>
</text>

我希望在所有&#39;之前和之后添加处理指令。文本。像这样:

<text>
text<?Pub _newline>and<?Pub _newline>text<?Pub _newline>and<?Pub _newline>text
<stop/>
text<?Pub _newline>and<?Pub _newline>text<?Pub _newline>and<?Pub _newline>text
<stop/>
text<?Pub _newline>and<?Pub _newline>text<?Pub _newline>and<?Pub _newline>text
<stop/>
</text>

我不知道如何在文本中添加PI元素。如果我设置为字符串,则会转义:&gt;?Pub _newline&lt;

1 个答案:

答案 0 :(得分:1)

示例文档中的text元素包含六个节点作为子节点:

  • 三个文本节点,每个节点包含文本text and text and text
  • 三个元素(每个元素的名称为stop)。

为了达到理想的结果,我们需要将每个Text节点分解为Text节点和Processing Instruction节点。

在dom4j中,我们可以使用父元素的content来完成此操作。此方法返回元素的所有子节点的列表,如果我们对此列表进行更改,XML文档也会更新。

因此,我们获取元素的内容列表,遍历所有子节点,当我们找到包含and的Text节点时,将Text节点拆分成片并插入新片段进入清单。

这是一种演示此方法的方法。传递一个元素,它将按要求插入处理指令:

import org.dom4j.*;
import org.dom4j.tree.*;

// ...

public void insertProcessingInstructions(Element element) {
    List nodes = element.content();
    final String splitter = " and ";
    int index = 0;
    while (index < nodes.size()) {
        if (nodes.get(index) instanceof Text) {
            Text textNode = (Text)nodes.get(index);
            String text = textNode.getText();
            int andPos = text.indexOf(splitter);
            if (andPos >= 0) {
                String beforeText = text.substring(0, andPos);
                String afterText = text.substring(andPos + splitter.length());
                textNode.setText(beforeText);
                nodes.add(index + 1, new DefaultProcessingInstruction("Pub", "_newline"));
                nodes.add(index + 2, new DefaultText(splitter.trim()));
                nodes.add(index + 3, new DefaultProcessingInstruction("Pub", "_newline"));
                nodes.add(index + 4, new DefaultText(afterText));
                // Move to the last Text node created, in case it contains another
                // occurrence of the splitter string.
                index += 4; 
            } else {
                // No more occurrences of the splitter string in this Text node.
                ++index;
            }
        } else {
            // Not a Text node.
            ++index;
        }
    }
}