2012-02-12 22 views
0

私はDOMを初めて使用しています。次の要件を満たしています。 私は、以下の単純化されたXMLの構造を有する:全ての<C>要素(<R>の子供)Java:DOM名前リストからノード名を変更する方法

<?xml version="1.0"?> 
<ExportData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<DataSet> 
    <Tables> 
     <Table> 
      <Rows> 
       <R> 
        <C>101</C> 
        <C>1503</C> 
        <C>2012-02-09 00:00:00</C> 
       </R> 
       <R> 
        <C>101</C> 
        <C>1503</C> 
        <C>2012-02-09 00:00:00</C> 
       </R> 
      </Rows> 
     </Table> 
    </Tables> 
</DataSet> 
</ExportData> 

を私は3つの文字列のリストに従って名前を変更する必要があります。 ので、出力は次のようになります。

<?xml version="1.0"?> 
<ExportData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<DataSet> 
    <Tables> 
     <Table> 
      <Rows> 
       <R> 
        <Name1>101</Name1> 
        <Name2>1503</Name2> 
        <Name3>2012-02-09 00:00:00</Name3> 
       </R> 
       <R> 
        <Name1>101</Name1> 
        <Name2>1503</Name2> 
        <Name3>2012-02-09 00:00:00</Name3> 
       </R> 
      </Rows> 
     </Table> 
    </Tables> 
</DataSet> 

を私はDOMはそれを行うための最善の選択肢だろうと思いました。そして、私は、次のを思い付いた:

import java.io.File; 
import java.io.FileInputStream; 
import java.util.ArrayList; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.*; 
import renameElementNames.DOMUtils; 

public class ParseNavigate { 

public static void main(String[] args) throws Exception { 
    final DOMImplementation domImpl = DOMUtils.getImplementationFromRegistry(DOMUtils.DOM_FEATURE_Core_30_LS); 
    final Document doc = DOMUtils.parse(domImpl, new FileInputStream("examplefiles/1503_roh_2012-02-09small.xml")); 
    changeTagNames(doc); 
    writeXmlFile(doc,"output.xml"); 
} 


public static void changeTagNames (Document doc){ 
    ArrayList<String> attlist = new ArrayList<String>(); 
    String name1 = "Name1";String name2 = "Name2";String name3 = "Name3"; 
    attlist.add(name1);attlist.add(name2);attlist.add(name3); 

    Node rows = doc.getElementsByTagName("Rows").item(0); 
    NodeList rs = rows.getChildNodes(); 


    for(int i=0;i<rs.getLength();i++){ 
     Node r = rs.item(i); 
     NodeList cs = r.getChildNodes(); 
     System.out.println(rs.getLength()); 
     for(int j=0;j<cs.getLength();j++){ 
      System.out.println(cs.getLength()); 
      Node c = cs.item(j); 
      if(c.getNodeType() == Node.ELEMENT_NODE){ 
       doc.renameNode(c,c.getNamespaceURI(),attlist.get(j)); 
      } 
     } 
    } 
} 

public static void writeXmlFile(Document doc, String filename) { 
    try { 
     // Prepare the DOM document for writing 
     Source source = new DOMSource(doc); 

     // Prepare the output file 
     File file = new File(filename); 
     Result result = new StreamResult(file); 

     // Write the DOM document to the file 
     Transformer xformer = TransformerFactory.newInstance().newTransformer(); 
     xformer.transform(source, result); 
    } catch (TransformerConfigurationException e) { 
    } catch (TransformerException e) { 
    } 
} 
} 

のでchangeTagNames方法は、作業を行うことになっています。私は3つの名前を保持するArrayListを持っています。しかし、私のArrayListと私のcs - NodeListのインデックスは同じではありません。私は3 <C>要素を持っていますが、NodeList csには3つではなく7つのノードがあります。

どのように私がこれを解決できるか知っていますか?または、これを達成するための別の、より良い、よりエレガントな方法がありますか?

はあなたの助けとよろしく、 ピーター

答えて

1

jOOXをこのジョブに使用し、ロジックをjqueryのようなスタイルで書き込むことができます。例:あなたが見ることができるように

// Create the list of new tag names 
final List<String> names = Arrays.asList("Name1", "Name2", "Name3"); 
final Document doc = ... 

// Find all <R/> elements and iterate over their <C/> children 
$(doc).find("R").children("C").each(new Each() { 
    public void each(Context context) { 

    // Get the appropriate tag name corresponding to the iteration index 
    String newTagName = names.get(context.elementIndex() % names.size()); 

    // Use the DOM API to rename the node 
    doc.renameNode(context.element(), "", newTagName); 
    } 
}); 

// Check results 
System.out.println($(doc)); 

、これはJavaでわずか数行で行うことができます。別のオプション

final Document doc = ... 

// Iterate over <R/> elements 
for (Match r : $(doc).find("R").each()) { 

    // Iterate over <C/> children and rename nodes 
    Match c = r.children("C"); 
    for (int i = 0; i < c.size(); i++) { 
    doc.renameNode(c.get(i), "", "Name" + (i + 1)); 
    } 
} 

// Check results 
System.out.println($(doc)); 
+0

こんにちはルーカス、ありがとう。私は "jOOX-1.0.0.zip"をダウンロードしてライブラリとして追加しました。しかし、 "import static org.joox.JOOX。*;" 「インポートorg.jooxを解決できません」というエラーが発生します。私が間違っていることを私に教えてください。 – Peter

+0

@Peter:あなたのコンパイラ/ランタイムクラスパスにライブラリを置く必要があります...例については[この質問(http://stackoverflow.com/questions/4590739/setting-the-classpath)を参照してください –

+0

ありがとうLukas 、それは働いている! – Peter

1

いただきありがとうございますが、より良いフィット感、このためかもしれないXSLTのように思えます。 position()関数を使用して要素名を生成することができます。詳細はthis answerをご覧ください。

+0

こんにちはHertzsprung、ありがとう。はい、私はあなたに同意するが、要件は、私はJavaを使用することができますです。よろしく、ピーター – Peter

関連する問題