Veljko
Veljko

Reputation: 1808

XSLT CHOOSE function - select value from specific element when element name appears more times in XML

I have this XML.

<?xml version="1.0"?>
<data>
    <ns11_tl>
        <ns9_userLabel>192.168.188</ns9_userLabel>
        <ns11_aEndTpRef>
            <ns7_rdn>
                <ns7_type>MD</ns7_type>
                <ns7_value>Server</ns7_value>
            </ns7_rdn>
            <ns7_rdn>
                <ns7_type>ME</ns7_type>
                <ns7_value>192.168</ns7_value>
            </ns7_rdn>
            <ns7_rdn>
                <ns7_type>FTP</ns7_type>
                <ns7_value>1:2:3-4</ns7_value>
            </ns7_rdn>
        </ns11_aEndTpRef>
    </ns11_tl>
</data>

I want to put into the field STRING2 value from ns7_value element but only if ns7_type has value ME. I tried with this code but it did not work result is empty. I tried for testing purposes to put into the DESC element value from any ns7_type (just for testing) and I can retrieve it but code always returns null for ns7_value element.

<xsl:template match="/"> 
    <max:SyncDWDMLINK>
    <max:DWDMLINKSet>
    <xsl:apply-templates select="data/ns11_tl" />
    </max:DWDMLINKSet>  
    </max:SyncDWDMLINK>
</xsl:template> 
  <xsl:template match="ns11_tl"> 
    <max:DWDM>
        <max:DESC><xsl:value-of select="ns11_aEndTpRef/ns7_rdn/ns7_type"/></max:DESC>
        <max:STRING2>
        <xsl:choose>
        <xsl:when test="contains(ns11_aEndTpRef/ns7_rdn/ns7_type,'ME')">
        <xsl:value-of select="ns11_aEndTpRef/ns7_rdn/ns7_value"/>
        </xsl:when>
        </xsl:choose>
        </max:STRING2>
    </max:DWDM>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 1159

Answers (3)

Carlos
Carlos

Reputation: 1449

Assuming you want the same amount of "DWDM" nodes as "ns7_rdn" of your input, you should make the following changes to your xsl:

 <xsl:template match="/">
    <max:SyncDWDMLINK>
        <max:DWDMLINKSet>
            <xsl:apply-templates select="//ns7_rdn" />
        </max:DWDMLINKSet>
    </max:SyncDWDMLINK>
</xsl:template>
<xsl:template match="ns7_rdn">
    <max:DWDM>
        <max:DESC><xsl:value-of select="ns7_type"/></max:DESC>
        <max:STRING2>
            <xsl:if test="contains(ns7_type,'ME')">
                <xsl:value-of select="ns7_value"/>
            </xsl:if>
        </max:STRING2>
    </max:DWDM>
</xsl:template>

This will produce this result which I suppose is what you expect

<max:SyncDWDMLINK>
<max:DWDMLINKSet>
<max:DWDM>
<max:DESC>MD</max:DESC>
<max:STRING2/>
</max:DWDM>
<max:DWDM>
<max:DESC>ME</max:DESC>
<max:STRING2>192.168</max:STRING2>
</max:DWDM>
<max:DWDM>
<max:DESC>FTP</max:DESC>
<max:STRING2/>
</max:DWDM>
</max:DWDMLINKSet>
</max:SyncDWDMLINK>

Please note the select in the "apply-templates" and besides it works with the "contains" function, you can just use <xsl:if test="ns7_type='ME'">

Hope this helps

Upvotes: 1

Tim C
Tim C

Reputation: 70648

The are multiple ns7_type elements in your XML. You current statement ns11_aEndTpRef/ns7_rdn/ns7_type is selecting all of them, but when this statement is used in a contains function, which expects a string as the first parameter, it will only select the first node in the set.

You don't actually need xsl:choose here. You can simplify the code by making use of a condition in the xpath, like so:

  <xsl:template match="ns11_tl"> 
    <max:DWDM>
        <max:DESC><xsl:value-of select="ns11_aEndTpRef/ns7_rdn/ns7_type"/></max:DESC>
        <max:STRING2>
            <xsl:value-of select="ns11_aEndTpRef/ns7_rdn[ns7_type='ME']/ns7_value"/>
        </max:STRING2>
    </max:DWDM>
  </xsl:template>

Upvotes: 1

imhotap
imhotap

Reputation: 2500

Try

<xsl:apply-templates select="data" />

instead.

Upvotes: 0

Related Questions