Background
I'm designing a Perl application that uses XML files as inputs for config and settings information. There will be a hierarchy of documents, with global data overridden by more local information.
My program will be invoked with the most local settings file which will contain paths to more general files. Some local settings will be absolute, and which these are would be hard coded in the program.
The initialization task is to get the settings for an invocation from the highest level, reading them in and then going on to each level and merge/join them as a single XML document.
Sample Data
Global_layouts_100.xml
<CONFIG>
<GRP1>
<FIELD foo="abs" format="%.4f">QTY</FIELD>
<FIELD default="" format="%.2f">COST</FIELD>
<FIELD default="0" format="%.2f">AMT</FIELD>
<FIELD default="1960-01-01" format="YYYMMDD">TRANDATE</FIELD>
<FIELD>ACCOUNT</FIELD>
<FIELD default="0">ACCT_TYPE</FIELD>
</GRP1>
<GRP2>
<FIELD> 1 </FIELD>
<FIELD> 2 </FIELD>
<FIELD> 3 </FIELD>
</GRP2>
</CONFIG>
Global_properties_100.xml
<CONFIG>
<CUS>
<GRP>GRP1</GRP>
<HDR>CUSTOMER</HDR>
<TLR>TLR${cnt}</TLR>
</CUS>
<XYZ>
<GRP>GRP2</GRP>
<HDR>ACCOUNTS</HDR>
<TLR>TLR${cnt}</TLR>
</XYZ>
</CONFIG>
Global_70.xml
<CONFIG>
<PARENT_SETTINGS>Global_layouts_100</PARENT_SETTINGS>
<PARENT_SETTINGS>Global_properties_100</PARENT_SETTINGS>
<LOOKUPS>
<MAP type="file">
<NAME>ACCT_TYPE_LOOKUP</NAME>
<PATH>${PATH}acct_type.csv</PATH>
<HEADERS>
<COLUMN>ACCT_TYPE</COLUMN>
<COLUMN>SOURCE_VALUE</COLUMN>
</HEADERS>
<KEYS>
<COLUMN>SOURCE_VALUE</COLUMN>
</KEYS>
</MAP>
</LOOKUPS>
</CONFIG>
local.xml
<CONFIG>
<PARENT_SETTINGS>Global_70</PARENT_SETTINGS>
<BATCH>
<CUS>
<SRCFILE type="csv" delimiter="|">/path/to/src_file</SRCFILE>
<OUTFILE>/path/to/out_file</OUTFILE>
<FIELDS>
<CUSTOMER>&CUSTOMER;</CUSTOMER>
<QTY default="0.0" col="23"></QTY>
<COST format="%.4f" col="21"></COST>
<FEE col="18"></FEE>
</FIELDS>
</CUS>
<XYZ>
<SRCFILE />
<OUTFILE />
<FIELDS>
<FIELD_1 />
<FIELD_2 />
<FIELD_3 />
<FIELD_4 />
<FIELD_5 />
</FIELDS>
</XYZ>
</BATCH>
</CONFIG>
Now, if the program would be given the local.xml to start and CUS as an arg to process I'd like to see this XML (or equivalant perl data structure):
<CONFIG>
<HDR>CUSTOMER</HDR>
<TLR>TLR${cnt}</TLR>
<SRCFILE type="csv" delimiter="|">/path/to/src_file</SRCFILE>
<OUTFILE>/path/to/out_file</OUTFILE>
<LOOKUPS>
<MAP type="file">
<NAME>ACCT_TYPE_LOOKUP</NAME>
<PATH>${PATH}acct_type.csv</PATH>
<HEADERS>
<COLUMN>ACCT_TYPE</COLUMN>
<COLUMN>SOURCE_VALUE</COLUMN>
</HEADERS>
<KEYS>
<COLUMN>SOURCE_VALUE</COLUMN>
</KEYS>
</MAP>
</LOOKUPS>
<CUS>
<FIELD foo="abs" format="%.4f" default="0.0" col="23">QTY</FIELD>
<FIELD default="" format="%.4f" col="21">COST</FIELD>
<FIELD default="0" format="%.2f">AMT</FIELD>
<FIELD default="1960-01-01" format="YYYMMDD">TRANDATE</FIELD>
<FIELD>ACCOUNT</FIELD>
<FIELD default="0">ACCT_TYPE</FIELD>
<FIELDS>
<CUSTOMER>&CUSTOMER;</CUSTOMER>
<QTY default="0.0" col="23"></QTY>
<COST format="%.4f" col="21"></COST>
<FEE col="18"></FEE>
</FIELDS>
</CUS>
</CONFIG>
And, if the program would be given the local.xml to start and XYZ as an arg to process I'd like to see this XML (or equivalant perl data structure):
<CONFIG>
<HDR>ACCOUNTS</HDR>
<TLR>TLR${cnt}</TLR>
<SRCFILE />
<OUTFILE />
<LOOKUPS>
<MAP type="file">
<NAME>ACCT_TYPE_LOOKUP</NAME>
<PATH>${PATH}acct_type.csv</PATH>
<HEADERS>
<COLUMN>ACCT_TYPE</COLUMN>
<COLUMN>SOURCE_VALUE</COLUMN>
</HEADERS>
<KEYS>
<COLUMN>SOURCE_VALUE</COLUMN>
</KEYS>
</MAP>
</LOOKUPS>
<XYZ>
<FIELD> 1 </FIELD>
<FIELD> 2 </FIELD>
<FIELD> 3 </FIELD>
<FIELDS>
<FIELD_1 />
<FIELD_2 />
<FIELD_3 />
<FIELD_4 />
<FIELD_5 />
</FIELDS>
</XYZ>
</CONFIG>
Question
What is the most efficient way of merging these XML documents?
I can do it myself with the data structures returned by XML::Simple
, or maybe there are some other XML tools I should use?
I hope my question is clear enough and does not need sample XML data. If you need to see something then I can post some sample stuff.
The question in brief is, what is the best way to merge a hierarchy of individual XML documents?