2014-10-24 3 views
1

У меня есть сильфона XML:синтаксического анализа XML с помощью DOM Java

<modelingOutput> 
    <listOfTopics> 
     <topic id="1"> 
      <token id="354">wish</token> 
     </topic> 
    </listOfTopics> 
    <rankedDocs> 
     <topic id="1"> 
      <documents> 
       <document id="1" numWords="0"/> 
       <document id="2" numWords="1"/> 
       <document id="3" numWords="2"/> 
      </documents> 
     </topic> 
    </rankedDocs> 
    <listOfDocs> 
     <documents> 
      <document id="1"> 
       <topic id="1" percentage="4.790644689978203%"/> 
       <topic id="2" percentage="11.427632949428334%"/> 
       <topic id="3" percentage="17.86913349249596%"/> 
      </document> 
     </documents> 
    </listOfDocs> 
</modelingOutput> 

Ι Хотите разобрать этот XML-файл и получить идентификатор темы и процент от ListofDocs

Первый способ - получить весь элемент документа из xml, а затем проверить, является ли узел grandfather ListofDocs. Но документ элемента существует в rankedDocs и в listOfDocs, поэтому у меня есть очень большой список.

Так что интересно, существует ли лучшее решение для синтаксического анализа этого xml-кода, исключающего if?

Мой код:

public void parse(){ 
    Document dom = null; 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    InputSource is = new InputSource(new StringReader(xml)); 

    dom = db.parse(is); 

    Element doc = dom.getDocumentElement(); 
    NodeList documentnl = doc.getElementsByTagName("document"); 
    for (int i = 1; i <= documentnl.getLength(); i++) { 
     Node item = documentnl.item(i); 
     Node parentNode = item.getParentNode(); 
     Node grandpNode = parentNode.getParentNode(); 
     if(grandpNode.getNodeName() == "listOfDocs"{ 
      //get value 
     } 
    } 
} 

ответ

2

Во-первых, при проверке имени узла вы не должны сравнивать String с с использованием ==. Всегда используйте метод equals.

Вы можете использовать XPath для оценивать только документ topic элементы под listOfDocs:

XPathFactory xPathFactory = XPathFactory.newInstance(); 
XPath xPath = xPathFactory.newXPath(); 
XPathExpression xPathExpression = xPath.compile("//listOfDocs//document/topic"); 

NodeList topicnl = (NodeList) xPathExpression.evaluate(dom, XPathConstants.NODESET); 
for(int i = 0; i < topicnl.getLength(); i++) { 
    ... 
+0

Да, я знаю. Интересно, существует ли лучшее решение в dom? – Jimmysnn

1

Если вы не хотите использовать, если заявление вы можете использовать XPath, чтобы получить элемент, который нужно непосредственно.

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.parse("source.xml"); 
XPathFactory xPathfactory = XPathFactory.newInstance(); 
XPath xpath = xPathfactory.newXPath(); 
XPathExpression expr = xpath.compile("/*/listOfDocs/documents/document/topic"); 
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 

for (int i = 0; i < nodes.getLength(); i++) { 
    System.out.println(nodes.item(i).getAttributes().getNamedItem("id")); 
    System.out.println(nodes.item(i).getAttributes().getNamedItem("percentage")); 
} 

Пожалуйста, проверьте проект GitHub here.

Надеюсь, это поможет.

+0

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

0

Мне нравится использовать XMLBeam для таких задач:

public class Answer { 

    @XBDocURL("resource://data.xml") 
    public interface DataProjection { 

     public interface Topic { 
      @XBRead("./@id") 
      int getID(); 

      @XBRead("./@percentage") 
      String getPercentage(); 
     } 

     @XBRead("/modelingOutput/listOfDocs//document/topic") 
     List<Topic> getTopics(); 
    } 

    public static void main(final String[] args) throws IOException { 
     final DataProjection dataProjection = new XBProjector().io().fromURLAnnotation(DataProjection.class); 
     for (Topic topic : dataProjection.getTopics()) { 
      System.out.println(topic.getID() + ": " + topic.getPercentage()); 
     } 
    } 
} 

Существует даже удобный способ преобразования процента в float или double. Скажите, если вам нравится пример.

Смежные вопросы