Reputation: 355
Using the following xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*"/>
<xsl:template match="/all">
<xsl:apply-templates select="linuxdirs/dir" />
</xsl:template>
<xsl:template match="dir[@runall='no']">
<xsl:for-each select="sqlfile">
<filename>
<xsl:value-of select="@filename" />
<xsl:text> </xsl:text>
</filename>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when I apply to the following xml:
<?xml version="1.0"?>
<?xml-stylesheet href="dirs.xsl" type="text/xsl"?>
<all>
<topdir><dir td_id="1" dirname="./Database/APPS" owner="APPS" /></topdir>
<linuxdirs>
<dir td_id="1" did="1" dirname="./Database/APPS/DDL/Create/Tables" runall="no">
<sqlfile f_id="1" filename="create_account_table.sql" />
</dir>
<dir td_id="1" did="2" dirname="./Database/APPS/DCL/Grant" runall="no">
<sqlfile f_id="1" filename="xla_distribution_links.sql" />
<sqlfile f_id="2" filename="grant_to_app_role.sql" />
</dir>
<dir td_id="1" did="3" dirname="./Database/APPS/DML/Insert" runall="yes"></dir>
</linuxdirs>
</all>
I do not see all file names appear, only the last one ever appears, which for the above sample xml is xla_distribution_links.sql.
Can anybody suggest how to obtain the following output using xslt 1.0?
./Database/APPS/DDL/Create/Tables/create_account_table.sql
./Database/APPS/DCL/Grant/xla_distribution_links.sql
./Database/APPS/DCL/Grant/grant_to_app_role.sql
I am using xsltproc to parse xml on the command line.
I only get a single file name output using the code you've posted:
I still only get a single file output when using your code, although the format is now correct, so thanks for that, but why is it only showing a single file?
$ xsltproc -o out.csv dirs2.xsl dirs.xml
$ cat out.csv
./Database/APPS/DCL/Grant/xla_distribution_links.sql
$ cat dirs2.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*"/>
<xsl:template match="/all">
<xsl:apply-templates select="linuxdirs/dir[@runall='no']" />
</xsl:template>
<xsl:template match="dir">
<xsl:variable name="path" select="@dirname" />
<xsl:for-each select="sqlfile">
<filename>
<xsl:value-of select="$path" />
<xsl:text>/</xsl:text>
<xsl:value-of select="@filename" />
<xsl:text> </xsl:text>
</filename>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
$ cat dirs.xml
<?xml version="1.0"?>
<?xml-stylesheet href="dirs.xsl" type="text/xsl"?>
<all>
<topdir><dir td_id="1" dirname="./Database/APPS" owner="APPS" /></topdir>
<linuxdirs>
<dir td_id="1" did="1" dirname="./Database/APPS/DDL/Create/Tables" runall="yes">
<sqlfile f_id="1" filename="create_account_table.sql" />
</dir>
<dir td_id="1" did="2" dirname="./Database/APPS/DCL/Grant" runall="no">
<sqlfile f_id="1" filename="xla_distribution_links.sql" />
</dir>
<dir td_id="1" did="3" dirname="./Database/APPS/DML/Insert" runall="no"></dir>
</linuxdirs>
</all>
Upvotes: 0
Views: 89
Reputation: 117073
To get the result you show, you should do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*"/>
<xsl:template match="/all">
<xsl:apply-templates select="linuxdirs/dir[@runall='no']" />
</xsl:template>
<xsl:template match="dir">
<xsl:variable name="path" select="@dirname" />
<xsl:for-each select="sqlfile">
<filename>
<xsl:value-of select="$path" />
<xsl:text>/</xsl:text>
<xsl:value-of select="@filename" />
<xsl:text> </xsl:text>
</filename>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Note the predicate being moved from the match expression to xsl:apply-templates
. The way you have it, templates are applied to all dir
nodes, without exemption - and the built-in templates could produce unexpected results.
Upvotes: 1