XLS select =“$ my_parameter”不会评估为已解析的XML

时间:2016-12-20 22:39:35

标签: xslt

这是一个返回12的变量,这是我所期望的:

    <xsl:variable name="MM">
        <xsl:value-of select="../BIRTH_MONTH"/>
    </xsl:variable>

我希望将select子句基于参数。我想这样的事情:

<!-- $which_date has the value "BIRTH" -->

    <xsl:variable name="MM">
        <xsl:value-of select="concat('../', $which_date, '_MONTH')"/>
    </xsl:variable>

以上返回值../BIRTH_MONTH

我认为问题可能出在concat(),但下面是一个变体,它也会返回../BIRTH_MONTH的未评估结果:

<!-- $which_date has the value "../BIRTH_MONTH" -->

    <xsl:variable name="MM">
        <xsl:value-of select="$which_date"/>
    </xsl:variable>

(根据带引号,括号等的调整,在此处插入数十次尝试的历史记录)

如何在可以评估的表达式中使用$which_date

1 个答案:

答案 0 :(得分:0)

  
<xsl:variable name="MM">
    <xsl:value-of select="concat('../', $which_date, '_MONTH')"/>
</xsl:variable>
     

以上返回值为../ BIRTH_MONTH。

你想要

<xsl:variable name="MM" select="../*[name()=concat($which_date, '_MONTH')]"/>

这是一个完整的转型

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:param name="which_date" select="'BIRTH'"/>

  <xsl:template match="x">
    <xsl:variable name="MM" select=
         "../*[name()=concat($which_date, '_MONTH')]"/>
    <xsl:value-of select="$MM"/>
  </xsl:template>

  <xsl:template match="text()"/>
</xsl:stylesheet>

对以下XML文档应用此转换时(问题未提供):

<t>
 <x>1</x>
 <BIRTH_MONTH>12</BIRTH_MONTH>
</t>

产生了想要的正确结果

12

更新:根据您的其他类似问题,我们发现您需要参数化解决方案。

以下是一种可能的参数化解决方案:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pdateComponents" select="'|BIRTH_MONTH|BIRTH_DAY|BIRTH_YEAR|'"/>
 <xsl:param name="poutputDateName" select="'BIRTH_DATE'"/>

  <xsl:template match="/*">
    <xsl:apply-templates select=
     "*[*[contains($pdateComponents, concat('|',name(),'|'))]]" mode="dateHolder"/>
  </xsl:template>

  <xsl:template match="*" mode="dateHolder">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:element name="{$poutputDateName}">
        <xsl:apply-templates select=
        "*[contains($pdateComponents, concat('|',name(),'|'))]" mode="date">
          <xsl:sort select="substring-before($pdateComponents, concat('|',name(),'|'))"/>
        </xsl:apply-templates>
      </xsl:element>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*" mode="date">
    <xsl:value-of select=
         "concat(substring('/', 1 + (position() = 1)), normalize-space())"/>
  </xsl:template>
</xsl:stylesheet>

对以下XML文档应用此XSLT 1.0转换时

<RECORDS>
    <PERSON name="A">
        <BIRTH_YEAR> 1943 </BIRTH_YEAR>
        <BIRTH_MONTH>  04 </BIRTH_MONTH>
        <BIRTH_DAY>    01 </BIRTH_DAY>
    </PERSON>
    <PERSON name="B">
        <BIRTH_YEAR> 1957 </BIRTH_YEAR>
        <BIRTH_MONTH>  08 </BIRTH_MONTH>
        <BIRTH_DAY>    29 </BIRTH_DAY>
    </PERSON>
    <PERSON name="C">
        <BIRTH_YEAR> 1802 </BIRTH_YEAR>
        <BIRTH_MONTH>  12 </BIRTH_MONTH>
        <BIRTH_DAY>    14 </BIRTH_DAY>
    </PERSON>
    <PERSON name="D">
        <BIRTH_YEAR> 2015 </BIRTH_YEAR>
        <BIRTH_MONTH>  04 </BIRTH_MONTH>
        <BIRTH_DAY>    30 </BIRTH_DAY>
    </PERSON>
</RECORDS>

结果是

<PERSON name="A">
   <BIRTH_DATE>04/01/1943</BIRTH_DATE>
</PERSON>
<PERSON name="B">
   <BIRTH_DATE>08/29/1957</BIRTH_DATE>
</PERSON>
<PERSON name="C">
   <BIRTH_DATE>12/14/1802</BIRTH_DATE>
</PERSON>
<PERSON name="D">
   <BIRTH_DATE>04/30/2015</BIRTH_DATE>
</PERSON>

请注意

  1. 日期组件的名称在变换的全局参数中提供 - 它们不是静态知道的。
  2. 包含日期的输出元素的名称也作为转换的另一个全局参数的值提供。
  3. 在第一个组件中提供了用于构造日期的日期组件的顺序!
  4. 因此,上面提供的参数会导致美国日期输出。

    但是,如果我们提供此参数

     <xsl:param name="pdateComponents" select="'|BIRTH_DAY|BIRTH_MONTH|BIRTH_YEAR|'"/>
    

    然后转换的结果包含欧洲格式的日期:

    <PERSON name="A">
       <BIRTH_DATE>01/04/1943</BIRTH_DATE>
    </PERSON>
    <PERSON name="B">
       <BIRTH_DATE>29/08/1957</BIRTH_DATE>
    </PERSON>
    <PERSON name="C">
       <BIRTH_DATE>14/12/1802</BIRTH_DATE>
    </PERSON>
    <PERSON name="D">
       <BIRTH_DATE>30/04/2015</BIRTH_DATE>
    </PERSON>