2010-12-17 7 views
1

ich eine einfache xml-Datei habe zu lösen hier erstellt sind [Produkt]. Unter jedem [Produkt] Knoten gibt es zwei untergeordnete Knoten, [code] und [name], so sieht es im Grunde wie:Eine Frage, wie die Zeichenfolge Problem in Java

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

ich auch den folgenden Java-Code geschrieben haben, auf diese XML-Datei zu analysieren und entferne den Textinhalt des Knotens [product] und füge ihn zu einer JComboBox hinzu.

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()); 
} 

Der Code ganz einfach ist, ich zunächst die XML parsen und alle Produkt Knoten erhalten und sie in eine Nodelist setzen, und das ist ein productArrayList. Ich durchlaufe alle [product] Knoten, für jedes von ihnen, wenn es Kind-Knoten hat, dann nehme ich den zweiten Kind-Knoten (welcher der [Name] -Knoten ist) und lege den Textinhalt davon in die Array-Liste, und schließlich durchlaufe ich die arrayList und füge jedes Element zum Kombinationsfeld hinzu.

Das Problem, das ich habe, ist, wenn ich den [code] Kind-Knoten, was bedeutet "Knoten nameNode = nl.item (1)", wird es perfekt funktionieren; Wenn ich jedoch dieses Element (1) zu Element (2) ändere, um alle [Name] -Knoten zu extrahieren, wird das Kombinationsfeld eine Dropdown-Liste haben, aber alle Elemente sind leer, so wie ich 10 leere Zeichenfolgen eingefügt habe.

Auch wenn ich versuche, eine "Hello World" Zeichenfolge in das Kombinationsfeld nach dem obigen Code hinzuzufügen, wird der "Hello World" Artikel nach den 10 leeren Elementen angezeigt.

Ich habe den ganzen Nachmittag damit verbracht, das zu debuggen, aber immer noch keinen Durchbruch, das XML ist eigentlich ziemlich einfach und das Java ist auch einfach. Könnte jemand bitte ein paar Gedanken mit mir teilen? Danke vielmals!

+0

Ihre beste Wette ist einige Debug zu tun, um zu versuchen, die Region in Ihrem Code zu isolieren verursacht der Fehler, dann, wenn eine Lösung nicht herausfällt, post ein kleines kompilierbares lauffähiges Programm, das das Problem zeigt. –

+0

Haben Sie auch überlegt, mit XPath aus Ihrem Dokument zu extrahieren? –

+0

@Hovercraft Ich habe, aber diese Funktion muss in Java getan werden, könnten Sie eine Möglichkeit für mich vorschlagen, XPath zu Java-Klassen zu integrieren? – Kevin

Antwort

4

Es ist, weil die Knotenliste auch Textknoten enthält.

Wenn Sie den folgenden Code-Schnipsel zu Ihrem Code hinzufügen, werden Sie, dass

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

finden Sie geben die folgende Ausgabe für jede Iteration des Produkts

#text 
code 
#text 
name 
#text 

Dies bedeutet, dass Sie das bekommen müssen 3. Element, um den name Knoten zu erhalten.

Node nameNode = nl.item(3); 

Aber ich schlage vor, Sie verwenden XPath, um dieses Problem zu lösen.

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

das ist die schönste Lektion, die ich je hatte, danke! – Kevin

+0

Ich untersuche jetzt XSLT, und ich stieß auf den Abschnitt, in dem der Leerraum als Textknoten im XSLT-Prozessor betrachtet wird. Kann ich das, was wir hier haben, mit XSLT im Allgemeinen gleichsetzen? – Kevin

+0

Ich bin kein Experte in XSLT, aber soweit ich weiß, behandelt verschiedene XML-Parser die Leerzeichen anders. Ich denke, es könnte genauso sein wie für XSLT-Prozessoren. –

1

XPath diesen Ausdruck verwendet, wird leicht Ihr Problem lösen:

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

zB

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; 
    }