0

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?

3 Answers 3

1

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>
Sign up to request clarification or add additional context in comments.

1 Comment

I chose to not include those parts, but the XML has other Types too, Fax, E-mail etc. But I guess that won't matter in your solution, since I could just add those in after the first xsl:when.
1

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.

3 Comments

How does this work in my case where I also have other Types? They could be Fax or E-mail i.e, and these can't be more than one, nor should they have numbered tags as the phone numbers.
You didn't make any of that clear in your question. We can only answer the question put before us, and even then it depends on us understanding what is asked.
Sorry for that. I have updated the question so it's more clearer.
0

@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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.