2010-12-17 13 views
1
内の文字列の問題を解決する方法についての質問が

私はここで簡単なXMLファイルを作成しました[製品]です。各[製品]ノードの下に、2つのつの子ノード、[コード]と[名前]がありますが、それは基本的に次のようになります。Javaの

[product] 
    [code]ddd[/code] 
    [name]ssss[/name] 
    [/product] 

また、私は、このXMLファイルを解析するために、次のJavaコードを書いていると、 [product]ノードのテキストコンテンツを取り出し、JComboBoxに追加します。

docBuilder = docFactory.newDocumentBuilder(); 
doc = docBuilder.parse("http://roberthan.host56.com/productsNew.xml"); 

    NodeList productNodes = doc.getElementsByTagName("product"); 

     productlist.clear(); 
     for (i = 0; i < productNodes.getLength(); i++) 
     { 


      Node childNode = productNodes.item(i); 

      if (childNode.hasChildNodes()) { 
       NodeList nl = childNode.getChildNodes(); 


       Node nameNode = nl.item(2); 
       productlist.add(nameNode.getTextContent()); 

      } 

     } 


final JComboBox productComboB = new JComboBox(); 
Iterator iterator = productlist.iterator(); 

while(iterator.hasNext()) 
{ 
productComboB.addItem(iterator.next().toString()); 
} 

コードは、私が最初にXMLを解析し、すべての製品のノードを取得し、ノードリストに入れて、非常に簡単です、そしてproductListはArrayListのです。すべての[product]ノードをループします。子ノードがある場合は、2番目の子ノード([name]ノード)を取り出し、そのテキストコンテンツを配列リストに入れます。最後に、arrayListをループし、各項目をコンボボックスに追加します。

問題は、「node nameNode = nl.item(1)」を意味する[code]子ノードを選択すると完全に機能します。ただし、すべての[name]ノードを抽出するためにアイテム(1)をアイテム(2)に変更すると、コンボボックスにドロップダウンリストが表示されますが、10個の空の文字列を挿入したように、

また、上記のコードの後に​​コンボボックスに「Hello World」という文字列を追加しようとすると、10個の空の項目の後ろに「Hello World」という項目が表示されます。

私は午後全体をこのようにデバッグするのに多くの時間を費やしましたが、まだ画期的なことはありませんでしたが、XMLは実際には非常に簡単でJavaも簡単です。誰も私にこのような考えを伝えてください。どうもありがとう!

+0

あなたの最善の策は、原因あなたのコード内の領域を分離しようとするいくつかのデバッグを行うことですエラーが発生した場合、解決策が脱落しない場合は、問題を示す小さなコンパイル可能な実行可能プログラムを投稿します。 –

+0

また、XPathを使用してドキュメントから抽出することを検討しましたか? –

+0

@Hovercraft私は持っていますが、この関数はJavaで実行する必要があります。私はJavaクラスにXPathを組み込む方法を提案できますか? – Kevin

答えて

4

ノードリストにもテキストノードが含まれているためです。

あなたのコードに次のコードを追加する場合は、

for(int j = 0;j<nl.getLength();j++){ 
    System.out.println(nl.item(j).getNodeName()); 
} 

それは、製品の反復ごとに

#text 
code 
#text 
name 
#text 

を次のような出力が得られます。これは、あなたが取得する必要がありますを意味していることがわかります3番目の要素を使用してnameノードを取得します。

Node nameNode = nl.item(3); 

しかし、この問題を解決するためにXPathを使用することをお勧めします。この式を使用して

NodeList nodelist = XPathAPI.selectNodeList(doc, "//products/product/name"); 
for (int i = 0; i < nodelist.getLength(); i++) { 
    productlist.add(nodelist.item(i).getTextContent()); 
} 
+0

これは私がこれまでに受けた中で最も美しいレッスンです! – Kevin

+0

私は今XSLTを勉強していますが、XSLTプロセッサで空白がテキストノードとみなされるセクションを見つけました。だから私はここにあるものをXSLTに一般的に当てはめることができますか? – Kevin

+0

私はXSLTの専門家ではありませんが、別のxmlパーサーが空白を別々に処理することが分かっている限り、だから私はXSLTプロセッサと同じかもしれないと思います。 –

1

XPathは簡単にあなたの問題を解決します:

String XPATH_EXPRESSION1 = "//name/text()"; 

例えば、

public static final String PRODUCTS_NEW = "http://roberthan.host56.com/productsNew.xml"; 
    public static final String XPATH_EXPRESSION1 = "//name/text()"; 

    public XmlFun() { 
    URL productsUrl; 
    try { 
     productsUrl = new URL(PRODUCTS_NEW); 
     List<String> nameList = xPathExtract(productsUrl.openStream()); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ParserConfigurationException e) { 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } catch (XPathExpressionException e) { 
     e.printStackTrace(); 
    } 
    } 

    private List<String> xPathExtract(InputStream inStream) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { 
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = domFactory.newDocumentBuilder(); 
    Document domDoc = builder.parse(inStream); 

    XPathFactory xFactory = XPathFactory.newInstance(); 
    XPath xpath = xFactory.newXPath(); 

    XPathExpression xExpr = xpath.compile(XPATH_EXPRESSION1); 
    NodeList nodes = (NodeList)xExpr.evaluate(domDoc, XPathConstants.NODESET); 

    List<String> resultList = new ArrayList<String>(); 
    for (int i = 0; i < nodes.getLength(); i++) { 
     String node = nodes.item(i).getNodeValue(); 
     resultList.add(node); 
    } 

    return resultList; 
    }