Search code examples
xmlapache-commons-config

Apache commons config ignores outermost XML tag? Why? Am I doing something wrong?


Ok, I used to use apache commons config years ago a little, and have probably forgotten some things.

I'm a little baffled by what's going on, and it seems counter-intuitive to me.

So, here's my code:

public static void main(String[] args) throws ConfigurationException {
    XMLConfiguration config = new XMLConfiguration("config/base-config.xml");
    config.setExpressionEngine(new XPathExpressionEngine());
    List<Object> recipients;
    recipients = config.getList("emailRecipients/recipient");
    System.out.println("Recipients: " + recipients.size());
    for (Object recipient : recipients) {
        System.out.println("\tRecipient: " + recipient);
    }
}

And here's my xml config file:

<?xml version="1.0" encoding="UTF-8"?>
<emailRecipients>
    <recipient>[email protected]</recipient>
    <recipient>[email protected]</recipient>
</emailRecipients>

However, my code won't read the recipient tags as I expect.

Instead, I have to modify my config file to look like so:

<?xml version="1.0" encoding="UTF-8"?>
<arbitrary-outer-tag>
    <emailRecipients>
        <recipient>[email protected]</recipient>
        <recipient>[email protected]</recipient>
    </emailRecipients>
</arbitrary-outer-tag>

So, it seems like whatever the outermost tag is has to be disregarded in the XPath expression when looking for the configuration items I need.

Why is that? Is this by design? Am I doing something incorrectly?


Solution

  • You are correct. In Apache Commons Configuration, it is by design that the root is ignored in specifying keys. Consider this example from the Apache Commons Config User Guide:

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <gui-definition>
      <colors>
        <background>#808080</background>
        <text>#000000</text>
        <header>#008000</header>
        <link normal="#000080" visited="#800080"/>
        <default>${colors.header}</default>
      </colors>
      <rowsPerPage>15</rowsPerPage>
      <buttons>
        <name>OK,Cancel,Help</name>
      </buttons>
      <numberFormat pattern="###\,###.##"/>
    </gui-definition>
    

    And the following affirmation that the root is ignored:

    The root element is ignored when constructing keys. In the example you do not write gui-definition.color.text, but only color.text.

    Be assured that you are not alone in wondering about this, especially with XPath keys. But at least it's consistent. For this XML document,

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    
    <database>
      <tables>
        <table tableType="system">
    

    XPaths have to ignore the root element too:

    HierarchicalConfiguration config = ...
    config.setExpressionEngine(new XPathExpressionEngine());
    
    // Now we can use XPATH queries:
    List<Object> fields = config.getList("tables/table[1]/fields/name");