Reputation: 106
This is the issue: The transformed XSLT is supposed to show two phone numbers, <Phone_1> and <Phone_2>, one for each. The Fax tag is just added for reference.
This is a snippet of the XML I have to transform:
<DirPartyContactInfoView>
<Locator>08-922100</Locator>
<Type>Phone</Type>
</DirPartyContactInfoView>
<Locator>073-6564865</Locator>
<Type>Phone</Type>
</DirPartyContactInfoView>
<Locator>08-922150</Locator>
<Type>Fax</Type>
</DirPartyContactInfoView>
And here's my current take on the XSLT for this snippet. So far I've tried setting a variable as a condition, knowing that it can only set the variable value once and not modify it.
<xsl:for-each select="DirPartyContactInfoView">
<xsl:choose>
<xsl:when test="Type='Phone'">
<xsl:variable name="Phone1" />
<xsl:choose>
<xsl:when test="Phone1=''">
<xsl:variable name="Phone1" select="Locator" />
<Phone_1>
<xsl:value-of select="Locator" />
</Phone_1>
</xsl:when>
<xsl:otherwise>
<Phone_2>
<xsl:value-of select="Locator" />
</Phone_2>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="Type='Fax'">
<Fax>
<xsl:value-of select="Locator" />
</Fax>
</xsl:when>
</xsl:choose>
</xsl:for-each>
Yet I get two <Phone_2> on the output, and I'm all out of ideas. I'm guessing I can't use a variable like this. Any way to fix this?
Upvotes: 0
Views: 471
Reputation: 163458
@flaskis has responded to previous answers by changing the question, so I'm a bit reluctant to weigh in, but it might be that an appropraiate solution here is of the form
<xsl:template match="phone[1]">...</xsl:template>
<xsl:template match="phone[2]">...</xsl:template>
where different template rules are applied to the first and second phone elements.
Upvotes: 0
Reputation: 34576
That's hugely complicated for the (seemingly) simple requirements you have. If I've understood you right, try this:
<xsl:template match="/">
<xsl:apply-templates select='root/DirPartyContactInfoView[Type="Phone"]' />
</xsl:template>
<xsl:template match='DirPartyContactInfoView'>
<xsl:element name='phone_{position()}'>
<xsl:value-of select='Locator' />
</xsl:element>
</xsl:template>
I've assumed a root node root
because your XML doesn't show us the root node you have.
Demo (see output source).
A good rule of thumb in XSLT is that, if you find yourself heavily relying on for-each
constructs or variables, there's possibly a better way.
Upvotes: 1
Reputation: 4739
Do you really need to have a xsl:for-each
loop? You can access the <Locator>
element also directly with XPath:
//DirPartyContactInfoView[1]/Locator
//DirPartyContactInfoView[2]/Locator
If you still need the xsl:for-each
loop, maybe something like this helps:
<xsl:for-each select="DirPartyContactInfoView">
<xsl:choose>
<xsl:when test="Type='Phone'">
<xsl:choose>
<xsl:when test="position()='1'">
<Phone_1>
<xsl:value-of select="Locator" />
</Phone_1>
</xsl:when>
<xsl:otherwise>
<Phone_2>
<xsl:value-of select="Locator" />
</Phone_2>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:for-each>
Upvotes: 1