XSLT CHOOSE函数 - 当元素名称在XML中出现更多次时,从特定元素中选择值

时间:2017-01-10 13:24:03

标签: xml xslt

我有这个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>

我想在 STRING2 元素中添加 ns7_value 字段,但仅限 ns7_type 具有值 ME 。 我尝试使用此代码,但它没有工作结果是空的。 我尝试用于测试目的,从任何 DESC (仅用于测试)中输入 ns7_type 元素值,我可以检索它,但代码始终为 ns7_value 元素返回null。

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

3 个答案:

答案 0 :(得分:1)

XML中有多个ns7_type元素。您当前的语句ns11_aEndTpRef/ns7_rdn/ns7_type正在选择所有语句,但是当在contains函数中使用此语句时,该函数需要将字符串作为第一个参数,它将仅选择集合中的第一个节点。 / p>

您实际上并不需要xsl:choose。您可以通过在xpath中使用条件来简化代码,如下所示:

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

答案 1 :(得分:1)

假设您需要与输入的“ns7_rdn”相同数量的“DWDM”节点,则应对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>

这会产生这个结果,我认为这是你期望的结果

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

请注意“apply-templates”中的select,除了使用“contains”功能外,您还可以使用<xsl:if test="ns7_type='ME'">

希望这有帮助

答案 2 :(得分:0)

尝试

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

代替。