DOM4J Parse not returning any child nodes

2019-06-07 16:39发布

I am attempting to begin writing a program which uses DOM4j with which I wish to parse a XML file, save it to some tables and finally allow the user to manipulate the data.

Unfortunately I am stuck on the most basic step, the parsing.

Here is the portion of my XML I am attempting to include:

<?xml version="1.0"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.04">

   <BkToCstmrDbtCdtNtfctn>

        <GrpHdr>

            <MsgId>000022222</MsgId>

When I attempt to find the root of my XML it does return the root correctly as "Document". When I attempt to get the child node from Document it also correctly gives me "BkToCstmrDbtCdtNtfctn". The problem is that when I try to go any further and get the child nodes from "Bk" I can't. I get this in the console:

org.dom4j.tree.DefaultElement@2b05039f [Element: <BkToCstmrDbtCdtNtfctn uri: urn:iso:std:iso:20022:tech:xsd:camt.054.001.04 attributes: []/>]

Here is my code, I would appreciate any feedback. Ultimately I want to get the "MsgId" attribute back but in general I just want to figure how to parse deeper into the XML because in reality it probably has about 25 layers.

public static Document getDocument(final String xmlFileName){

        Document document = null;
        SAXReader reader = new SAXReader();
        try{
            document = reader.read(xmlFileName);
        }
        catch (DocumentException e)
        {
            e.printStackTrace();
    }
        return document;
    }

    public static void main(String args[]){

        String xmlFileName = "C:\\Users\\jhamric\\Desktop\\Camt54.xml";
        String xPath = "//Document";
        Document document = getDocument(xmlFileName);
        Element root = document.getRootElement();
        List<Node> nodes = document.selectNodes(xPath);

        for(Iterator i = root.elementIterator(); i.hasNext();){
            Element element = (Element) i.next();
            System.out.println(element);

        }

        for(Iterator i = root.elementIterator("BkToCstmrDbtCdtNtfctn");i.hasNext();){
            Element bk = (Element) i.next();
            System.out.println(bk);
        }
    }

}

标签: java dom4j
1条回答
孤傲高冷的网名
2楼-- · 2019-06-07 17:03

The best approach is probably to use XPath, but since the XML document uses namespaces, you cannot use the "simple" selectNodes methods in the API. I would create a helper method to easily evaluate any XPath expression on either the Document or the Element level:

public static void main(String[] args) throws Exception {

    Document doc = getDocument(...);

    Map<String, String> namespaceContext = new HashMap<>();
    namespaceContext.put("ns", "urn:iso:std:iso:20022:tech:xsd:camt.054.001.04");

    // Select the first GrpHdr element in document order
    Element element = (Element) select("//ns:GrpHdr[1]", doc, namespaceContext);
    System.out.println(element.asXML());

    // Select the text content of the MsgId element
    Text msgId = (Text) select("./ns:MsgId/text()", element, namespaceContext);
    System.out.println(msgId.getText());

}

static Object select(String expression, Branch contextNode, Map<String, String> namespaceContext) {
    XPath xp = contextNode.createXPath(expression);
    xp.setNamespaceURIs(namespaceContext);
    return xp.evaluate(contextNode);
}

Note that the XPath expression must use namespace prefixes that is mapped to the namespace URIs used in the input document, but that the actual value of the prefix doesn't matter.

查看更多
登录 后发表回答