user2981822
user2981822

Reputation: 31

iterating items with namespace prefix in XML using DOM4J

The problem is a namespace prefix. The below is a sample xml code.

<rss version="2.0">
    <channel>        
        <item>
            <ed:filing xmlns:ed="http://www.ed.com">
                <ed:name>ABC</ed:name>
                <ed:files>
                    <ed:file ed:id="1" ed:file="abc.htm" />
                    <ed:file ed:id="2" ed:file="abc.zip" />
                </ed:files>
            </ed:filing>
        </item>
        <item>
            <ed:filing xmlns:ed="http://www.ed.com">
                <ed:name>CDF</ed:name>
                <ed:files>
                    <ed:file ed:id="1" ed:file="cdf.htm" />
                    <ed:file ed:id="2" ed:file="cdf.zip" />
                </ed:files>
            </ed:filing>
        </item>   
    </channel>
</rss>

I would parse a xml code with Java and dom4j and print out something like;

Name    File1    File2
ABC     abc.htm  abc.zip
CDF     cdf.htm  cfd.zip

Here's my Java code;

SAXReader reader = new SAXReader();
Document document = reader.read( inputFile );           
List<Node> nodes = document.selectNodes("//rss/channel/item");

for (Node node : nodes) {
    ??? How can I access "ed:name" and "ed:file" ???
}

Upvotes: 1

Views: 772

Answers (1)

forty-two
forty-two

Reputation: 12817

There are several options, but here is one using XPath and namespace mappings:

    Map<String, String> nc = new HashMap<String, String>() {
        {
            put("ed", "http://www.ed.com");
        }
    };

    System.out.printf("Name\tFile 1\tFile 2\n");
    for (Node node : nodes) {
        XPath xp = document.createXPath(".//ed:name");
        xp.setNamespaceURIs(nc);
        String name = xp.selectSingleNode(node).getText();

        xp = document.createXPath(".//ed:file[@ed:id='1']/@ed:file");
        xp.setNamespaceURIs(nc);
        String f1 = xp.selectSingleNode(node).getText();

        xp = document.createXPath(".//ed:file[@ed:id='2']/@ed:file");
        xp.setNamespaceURIs(nc);
        String f2 = xp.selectSingleNode(node).getText();

        System.out.printf("%s\t%s\t%s\n", name, f1, f2);
    }

A bit annoying that you cannot reuse the XPath instance as in javax.xml.xpath.

Upvotes: 1

Related Questions