1

I'm used to C++ libraries for xml parsing, namely rapidxml and tinyxml. The java built in DOM parser makes absolutely no sense to me. After some struggle I was able to store the root node I need, but now I want to find a tag with a specific id.

Here is a sample xml:

<?xml version="1.0" encoding="UTF-8"?>
<adventure title="Test Adventure" author="Tester">
    <enemies>
        <enemy id="e1" difficulty="1">Enemy1</enemy>
    </enemies>
    <story>
        <narration id="n1" action="d1">It's adventure time!</narration>
        <decision id="d1">
            <description>Would you like to participate?</description>
            <choice action="n2">Yes, please.</choice>
            <choice action="n3">Not the slightest.</choice>
        </decision>
        <narration id="n2" action="end">Great choice!</narration>
        <narration id="n3" action="end">Okay...</narration>
    </story>
</adventure>

I have the <story> node stored in a Node instance. From there, I want to find nodes wiith a specific id (let's say the 'n3' node).

I want to use this method:

private Node findNode(String id) {
    Node node = storyNode.getFirstChild();
    while ( node != null ) {
        Element elem = (Element)node;
        if ( elem.getAttribute("id") == id ) {
            return node;
        }
        node = node.getNextSibling();
    }

    return null;
}

This would be my way to go with a C++ library, but this is very far from working... I don't understand why I have to typecast for such simple task. Why can't the Node have a method to get attributes with specifying the attribute name. The getFirstChild() doesn't even seem to return the first child...

The wrapper classes I found online are either 30 loops deep, or even harder to use. Why is this so complicated? What am I doing wrong?

3
  • Oddly enough, it's very similar to the implement in the .Net libraries, so I assume that it's based on recommends from the standard's bodies, who probably engineered the solution and never had to use... Commented Dec 10, 2013 at 5:01
  • @MadProgrammer It's madness really. NodeLists which you have to iterate through, but not with an iterator, because the only way to get a node out is with the .item(index) method, which returns a Node, which might be an Element and it goes on and on and on... I'd need three methods, one which can grab the next sibling, one to return a specific child element, or the first one if it's called without a parameter, and a third to read a specific attribute. I could not make this more difficult if I wanted to, something is really wrong here. Commented Dec 10, 2013 at 5:08
  • Personally, I wrote a little library to "wrap" up the madness...and yes, I even wrote a IterableNodeList...my gut feeling is it was designed and written by engineers...Great on paper...not so much for the people who actually have to use it ;) Commented Dec 10, 2013 at 5:10

1 Answer 1

3

Why the API is so...awesome...will come down to why and how it was designed. The solution, may be simpler then you think.

One of the features available to you is the XPath implementation, it's touted as a query language for XML.

So, instead of trying to loop through each node and each child node, you could simply use something like //*[@id='n1'] to find any node with the id attribute that equals n1 (for example).

Using your example XML and the following code...

try {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("Test.xml"));
    Node root = doc.getDocumentElement();

    XPath xPath = XPathFactory.newInstance().newXPath();

    XPathExpression xExpress = xPath.compile("//*[@id='n1']");
    NodeList nl = (NodeList)xExpress.evaluate(root, XPathConstants.NODESET);

    System.out.println("Found " + nl.getLength() + " matches");
} catch (SAXException | IOException | ParserConfigurationException | XPathExpressionException ex) {
    ex.printStackTrace();
}

This outputted

Found 1 matches

Take a look at XPath for some more details

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.