Reputation: 23
I am trying to loop child elements under import and export. Create a parent element fields and put all the elements which the name is field into it, just under import, not include the elements field under structure, Create element structures over all elements structure, and the last work is rename all the element with the value of attribute name. I just know copy all of them first and can not go to next step to create the right template.
input:
<?xml version='1.0'?>
<jco name="TEST" timestamp="1275691115508" version="1.0">
<import>
<field name="RESERVED_IN">12345</field>
<structure name="GM_HEADER">
<field name="PSTNG_DATE">2004-07-02</field>
<field name="DOC_DATE">2004-04-02</field>
</structure>
<structure name="TESTRUN">
<field name="TESTRUN"></field>
</structure>
</import>
<export>
<field name="RESERVED_OUT"></field>
<structure name="GM_HEADER_RET">
<field name="MAT_DOC"></field>
<field name="DOC_YEAR">0000</field>
</structure>
</export>
</jco>
desired output:
<?xml version="1.0" ?>
<jco version="1.0" name="TEST">
<import>
<fields>
<RESERVED_IN>12345</RESERVED_IN>
</fields>
<structures>
<GM_HEADER>
<PSTNG_DATE>2004-07-02</PSTNG_DATE>
<DOC_DATE>2004-04-02</DOC_DATE>
</GM_HEADER>
<TESTRUN>
<TESTRUN></TESTRUN>
</TESTRUN>
</structures>
</import>
<export>
<fields>
<RESERVED_OUT></RESERVED_OUT>
</fields>
<structures>
<GM_HEADER_RET>
<MAT_DOC></MAT_DOC>
<DOC_YEAR>0000</DOC_YEAR>
</GM_HEADER_RET>
</structures>
</export>
</jco>
Below is my xslt, but it seems messed up.
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="import">
<fields>
<xsl:for-each select="/field">
<xsl:call-template name="field" />
</xsl:for-each>
</fields>
<structures>
<xsl:for-each select="/structure">
<xsl:element name="{@name}">
<xsl:value-of select="." />
</xsl:element>
<xsl:call-template name="field" />
</xsl:for-each>
</structures>
</xsl:template>
<xsl:template name="field">
<xsl:for-each select="/field">
<xsl:element name="{@name}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:template>
Upvotes: 2
Views: 1382
Reputation: 167696
Use templates and apply-templates
, not for-each
, and it works out rather elegantly:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="import | export">
<xsl:copy>
<fields>
<xsl:apply-templates select="field"/>
</fields>
<structures>
<xsl:apply-templates select="structure"/>
</structures>
</xsl:copy>
</xsl:template>
<xsl:template match="field | structure">
<xsl:element name="{@name}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2