2012-01-26 2 views
1

を使用して再帰的にDOMノードを変換し、私はそうのようなDOMノードを持って言う:私は私の中で次の操作を行いますid属性を変換するには、Java

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

のorg.w3c.dom.Elementノード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> 

私は子ノードをループすることができますが、ノードは複数のレベルの子を持つことができます。この場合、ルートには2つのサブレベルがあります。しかし、より多くのサブレベルがある場合、各レベルの子ノードをループするのはちょっと面倒なようです。この作業を達成するためのより直接的なアプローチがありますか?

おかげで、 ソニー

答えて

2

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

私は、DOMノードに取り組んでいます。以前は明らかにされていないことを申し訳ありません。あなたのappraochもdomノードで使えますか? – sony

+0

この例では、W3C DOMを使用しています。オブジェクトは 'org.w3c.dom'パッケージにあります。私は輸入品を追加しました。 – laz

+0

変換が機能します。ありがとうございました!しかし、私が次のようにしようとすると:public void transform(Element parent、Element child){ Document parent_doc = parent.getOwnerDocument(); child =(要素)parent_doc.importNode(子、真); 0:予期しない例外:org.w3c.dom.DOMException:WRONG_DOCUMENT_ERR:ノードが別のドキュメントで使用されています。それを作成したものよりも。 org.w3c.dom.DOMException:WRONG_DOCUMENT_ERR:ノードが作成されたドキュメントとは別のドキュメントで使用されています。 – sony

0

あなたはid属性に追加されているプレフィックス値が一定になる場合は、XSLTを使用することができます。これは、単純なコードにつながる

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node"> 
    <xsl:element name="node"> 
     <xsl:attribute name="id"> 
     <xsl:value-of select="concat('prefix/', @id)" /> 
     </xsl:attribute> 

     <xsl:apply-templates/> 
    <xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

(これは...私の頭の上からちょうどたとえば、あなたが必要があると思い正確なコードではありません)が、あなたは、このようなXSLTインタプリタをロードする必要がありますxalanとして変換を実行します。 XSLTをまだ使用していない場合は、これが最良の方法かもしれませんが、Javaコードを使用してDOM構造を直接操作する別の方法です。あなたは、変更したいすべてのノードのリストを取得するためにXPathを使用することができ