преобразовать dom-узел рекурсивно, используя Java - PullRequest
1 голос
/ 26 января 2012

Скажем, у меня есть dom-узел, например:

org.w3c.dom.Элементный узел:

<node id="101">
  <node id="102">
    <node id="103" />
  </node>
  <node id="104">
    <node id="103" />
  </node>
</node>

Чтобы преобразовать атрибут id, я сделал бы следующее в моем коде Java:

String nodeId = node.getAttribute("id");
String newNodeId = "prefix/" + nodeId;
node.getAttributeNode("id").setValue(newNodeId);

Вышеуказанный узел затем преобразуется в:

<node id="prefix/101">
  <node id="102">
    <node id="103" />
  </node>
  <node id="104">
    <node id="103" />
  </node>
</node>

Но я хочу рекурсивно изменить все подузлы. Ожидаемый преобразованный узел:

<node id="prefix/101">
  <node id="prefix/102">
    <node id="prefix'103" />
  </node>
  <node id="prefix/104">
    <node id="prefix/103" />
  </node>
</node>

Я мог бы пройти через дочерние узлы, но тогда у узла может быть несколько уровней дочерних. В этом случае корень имеет два подуровня. Но если есть больше подуровней, то циклически проходить по дочерним узлам каждого уровня кажется немного неловким. Есть ли более прямой подход к решению этой задачи?

Спасибо, Sony

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Вы можете использовать XPath для получения списка всех узлов, которые вы хотите изменить:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

...

final String xml = "<node id=\"101\"><node id=\"102\"><node id=\"103\" /></node><node id=\"104\"><node id=\"103\" /></node></node>";
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document doc = db.parse(new InputSource(new StringReader(xml)));
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPath xpath = xpathFactory.newXPath();
final NodeList nodes = (NodeList) xpath.compile("//node[@id]").evaluate(doc, XPathConstants.NODESET);
for (int nodeNumber = 0; nodeNumber < nodes.getLength(); ++nodeNumber) {
    final Element node = (Element) nodes.item(nodeNumber);
    final String nodeId = node.getAttribute("id");
    final String newNodeId = "prefix/" + nodeId;
    node.getAttributeNode("id").setValue(newNodeId);
}

Теперь документ будет состоять из этого:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<node id="prefix/101">
    <node id="prefix/102">
        <node id="prefix/103" />
    </node>
    <node id="prefix/104">
        <node id="prefix/103" />
    </node>
</node>
0 голосов
/ 26 января 2012

Если префиксное значение, которое вы добавляете в атрибут id, будет постоянным, вы можете использовать XSLT.(Это был бы не тот код, который вам нужен ... просто пример с головы до ног)интерпретатор, такой как xalan, чтобы выполнить преобразование.Если вы еще не используете XSLT, это может быть или не быть лучшим подходом, но это еще одна альтернатива прямой манипуляции структурой DOM с помощью кода Java.

...