Reputation: 347
Can anyone help me with this.
I have this XML below
<?xml version="1.0" encoding="utf-8"?>
<Document>
<TopLevel>
<Header>
<Start>
<ID>
<Public> <!-- or Private-->
<Name>Org Name</Name>
<Address>Org Address</Address>
</Public>
</ID>
</Start>
</Header>
</TopLevel>
</Document>
after the <ID>
tag I can expect to have <Public>
or <Private>
And I have this XSLT below
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<TopLevel>
<xsl:apply-templates select="Document/TopLevel/Header"/>
</TopLevel>
</xsl:template>
<xsl:template match="Header">
<Start>
<xsl:if test="Start/ID/Public/Name!=''">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test="Start/ID/Private/Name!=''">
<xsl:value-of select="."/>
</xsl:if>
</Start>
</xsl:template>
<xsl:template match ="Start/ID/Public/Name">
<ID>
<Public>
<Name>
<xsl:value-of select="." />
</Name>
</Public>
</ID>
</xsl:template>
<xsl:template match ="Start/ID/Private/Name">
<ID>
<Private>
<Name>
<xsl:value-of select="." />
</Name>
</Private>
</ID>
</xsl:template>
</xsl:stylesheet>
My question is, can I combine the last two templates in one so that I will only call one whatever is displayed in the input XML?
Upvotes: 1
Views: 912
Reputation: 122374
As it stands you're not currently applying either of the two templates you've defined for public or private. You could indeed combine the two templates, for example:
<xsl:template match="Header">
<Start>
<xsl:apply-templates select="Start/ID/*/Name"/>
</Start>
</xsl:template>
<xsl:template match ="Start/ID/*/Name">
<ID>
<!-- choose element name dynamically based on its parent -->
<xsl:element name="{name(..)}">
<Name>
<xsl:value-of select="." />
</Name>
</xsl:element>
</ID>
</xsl:template>
but it may be better to use a completely different approach to the problem - you haven't provided your desired output in the question but from the look of these templates it's very similar to the input but with a few elements dropped or renamed. A good approach for these "minimal editing" sorts of transformations is to start with an "identity template" that copies the input to output unchanged, but then override this behaviour for certain elements to make the changes you require. You will find many many examples of this technique if you search on Stack Overflow for "identity template XSLT".
Upvotes: 4