ANT + XSLT2.0 + Merge xmls

Here should go questions about transforming XML with XSLT and FOP.
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

ANT + XSLT2.0 + Merge xmls

Post by msambasiva »

Hi
Apache Ant(TM) version 1.9.7
XSLT 2.0

We have two xmls in two different folders as below. We need to merge all the services into on xml as show in the expected xml.
tmp/atf/test.xml, tmp/fnd/test.xml, tmp/fsm/test.xml
tmp/atf/test.xml,
=================

Code: Select all

<serviceReference>
<services>
<chapterSummary>
<text>This chapter describes t</text>
</chapterSummary>
<service anchor="">
<name>ABC</name>
</service>

<service anchor="">
<name>DEF</name>
</service>
</services>
</serviceReference>
tmp/fnd/test.xml,
=================

Code: Select all

<serviceReference>
<services>
<chapterSummary>
<text>This chapter describes t</text>
</chapterSummary>
<service anchor="">
<name>XYZ</name>
</service>
<service anchor="">
<name>PQR</name>
</service>
</services>
</serviceReference>
Expected output:
==================
tmp/common/test.xml

=================

Code: Select all

<serviceReference>
<services>
<chapterSummary>
<text>This chapter describes t</text>
</chapterSummary>
<service anchor="">
<name>ABC</name>
</service>
<service anchor="">
<name>DEF</name>
</service>
<service anchor="">
<name>XYZ</name>
</service>
<service anchor="">
<name>PQR</name>
</service>
</services>
</serviceReference>
ANT SCRIPT:

Code: Select all

<xslt basedir="${dita.temp.dir}" destdir="${dita.temp.dir}${file.separator}common" style="${dita.plugin}${file.separator}xsl${file.separator}common_asset_merger.xsl" includes="atf/ fnd/ fsm/"
filenameparameter="filename"
filedirparameter="filedir"
>
</xslt>
XSLT:

Code: Select all

 <xsl:template match="/">
<xsl:message> Current file is <xsl:value-of select="$filename"/> in directory <xsl:value-of select="$filedir"/></xsl:message>
<xsl:variable name="inpath" select="string-join(tokenize(document-uri(/), '/')[position() lt last()], '/')"/>
<xsl:message>inpath:<xsl:value-of select="$inpath"/></xsl:message>
<xsl:variable name="files" select="collection($inpath)"/>
<xsl:for-each select="$files">
<xsl:message> Current processing file is <xsl:value-of select="current()"/></xsl:message>
</xsl:for-each>
</xsl:template>
Control looping through all the three folders automatically. But I want to loop through the folders in XSLT.
Please suggest any clue to merge the xmls as expected.

Thanks in advance,
Samba.
Radu
Posts: 9018
Joined: Fri Jul 09, 2004 5:18 pm

Re: ANT + XSLT2.0 + Merge xmls

Post by Radu »

Hi Samba,

There is an XSLT 2.0 function called "collection" which allows you to iterate and load all XML files from a specific folder:

https://stackoverflow.com/questions/859 ... 89#8595589

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: ANT + XSLT2.0 + Merge xmls

Post by msambasiva »

Thanks for your reply.
You are right. collection function allows to iterate all the files from a specific folder. But in my case, the xmls are spread under different folders in temp folder. like temp/atf/test.xml temp/fnd/test.xml
I am passing temp as base dir as shown below <xslt> tag.

Code: Select all


<xslt basedir="${dita.temp.dir}" destdir="${dita.temp.dir}${file.separator}common" style="${dita.plugin}${file.separator}xsl${file.separator}common_asset_merger.xsl" includes="atf/ fnd/ fsm/"
filenameparameter="filename"
filedirparameter="filedir"
>
</xslt>
I don't want ANT to loop through all the xmls of different directories automatically. Because, I want to iterate through all the xmls in my xsl file to extract the required information from each input xmls and put into target xml.

Any clue would be a great help!
Thanks,
Samba.
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: ANT + XSLT2.0 + Merge xmls

Post by msambasiva »

I tried some thing below in my xsl file. Looks It's invoking xsl file three times.

Code: Select all

<xsl:template match="/">
<xsl:message> Current file is <xsl:value-of select="$filename"/> in directory <xsl:value-of select="$filedir"/></xsl:message>
<xsl:variable name="inpath" select="string-join(tokenize(document-uri(/), '/')[position() lt last()], '/')"/>
<xsl:message>inpath:<xsl:value-of select="$inpath"/></xsl:message>
<xsl:variable name="temp_path" select="string-join(tokenize($inpath, '/')[position() lt last()], '/')"/>
<xsl:message>temp_path:<xsl:value-of select="$temp_path"/></xsl:message>

<xsl:variable name="files" select="collection($inpath)"/>
<xsl:message>files:<xsl:value-of select="$files"/></xsl:message>
</xsl:template>
Below console output repeating three times,
Console output:
[xslt] Processing C:\dita-ot-2.4.6\temp\temp20181109124740272\atf\test.xml to C:\dita-ot-2.4.6\temp\temp20181109124740272\common\atf\test.html
[xslt] Loading stylesheet C:\dita-ot-2.4.6\plugins\uae.dita.oer\xsl\common_asset_merger.xsl
[xslt] Current file is test.xml in directory atf
[xslt] inpath:file:/C:/dita-ot-2.4.6/temp/temp20181109124740272/atf
[xslt] temp_path:file:/C:/dita-ot-2.4.6/temp/temp20181109124740272
[xslt] files:
[xslt]
[xslt]
[xslt] This chapter describes the .....

Radu
Posts: 9018
Joined: Fri Jul 09, 2004 5:18 pm

Re: ANT + XSLT2.0 + Merge xmls

Post by Radu »

Hi,

Right, looking at how you invoke the <xslt> task in the ANT process right now, the XSLT processor will be invoked separately for each of the XML files matched by the "includes" pattern. In your case you should probably advice the <xslt> task to also use the same XSLT as the "XML" source because your XSLT will take care to iterate all other files.
Something like:

Code: Select all

<xslt basedir="${dita.temp.dir}" destdir="${dita.temp.dir}${file.separator}common" style="${dita.plugin}${file.separator}xsl${file.separator}common_asset_merger.xsl"
in="${dita.plugin}${file.separator}xsl${file.separator}common_asset_merger.xsl"
filenameparameter="filename"
filedirparameter="filedir"
>
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply