parse xml using dom java

爱⌒轻易说出口 提交于 2020-01-30 09:29:46

问题


I have the bellow xml:

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

Ι Want to parse this xml file and get the topic id and percentage from ListofDocs

The first way is to get all document element from xml and then I check if grandfather node is ListofDocs. But the element document exist in rankedDocs and in listOfDocs, so I have a very large list.

So I wonder if exist better solution to parse this xml avoiding if statement?

My code:

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

回答1:


First, when checking the node name you shouldn't compare Strings using ==. Always use the equals method instead.

You can use XPath to evaluate only the document topic elements under 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++) {
   ...



回答2:


If you do not want to use the if statement you can use XPath to get the element you need directly.

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

Please check GitHub project here.

Hope this helps.




回答3:


I like to use XMLBeam for such tasks:

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

There is even a convenient way to convert the percentage to float or double. Tell me if you like to have an example.



来源:https://stackoverflow.com/questions/26556878/parse-xml-using-dom-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!