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