XSLT多案例

时间:2015-09-08 12:46:05

标签: xml xslt

从一开始我就有了

<GTD>
  <LINE>
    <VAR_1_1>
      1010
    </VAR_1_1>
    <VAR_1_2>
      value of G_47_*_2 is G_47_*_1 = 1010
    </VAR_1_2>
    <VAR_1_3>
      value of G_47_*_3 is G_47_*_1 = 1010
    </VAR_1_3>
    <VAR_1_4>
      value of G_47_*_4 is G_47_*_1 = 1010
    </VAR_1_4>
    <VAR_2_1>
      2010
    </VAR_2_1>
    <VAR_2_2>  ... the same with 2010 and 5010...
  </LINE>
</GTD>

我需要获得结果信息

<VAR_1_1>
  <xsl:choose>
    <xsl:when test="../G_47_1_1/text()='1010'">
      <xsl:value-of select="../G_47_1_1/text()" />
    </xsl:when>
    <xsl:when test="../G_47_2_1/text()='1010'">
      <xsl:value-of select="../G_47_2_1/text()" />
    </xsl:when>
    <xsl:when test="../G_47_3_1/text()='1010'">
      <xsl:value-of select="../G_47_3_1/text()" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>0</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</CustomsFeeCode>

据我所知,应该使用 xsl:模板匹配

我知道如何在 teplate match 的一个块中获取一个值,但我如何将它用于一个数组中的多个值?

更新:

过程的逻辑:

  • 我在源xml中有12个元素(3个块乘4行)

  • 每个块可以分配给一个代码2010 3010或5010 in G_47 _ * _ 1 元素

  • 此代码的顺序可能不同,并非所有代码都可以存在 (例如,在G_47_1_1中仅为2010年,在G_47_1_1和2010年为5010 G_47_2_1)

  • 在目标xml中我需要填充12个元素(3个块乘4行)

  • 修复了这些元素的顺序(2010年4个元素,3010之后,之后 5010)

  • 即使源XML中没有这样的元素

  • ,所有这些元素都会出现

现在我使用这种结构

{{1}}

但是我需要复制它12次(对于目标XML中的每个元素) 有用。但我认为这不对

1 个答案:

答案 0 :(得分:1)

这种重复可以重写,正如您已经怀疑的那样。更改(通过使其成为有效的XML来修复):

<VAR_1_1>
  <xsl:choose>
    <xsl:when test="../G_47_1_1/text()='1010'">
      <xsl:value-of select="../G_47_1_1/text()" />
    </xsl:when>
    <xsl:when test="../G_47_2_1/text()='1010'">
      <xsl:value-of select="../G_47_2_1/text()" />
    </xsl:when>
    <xsl:when test="../G_47_3_1/text()='1010'">
      <xsl:value-of select="../G_47_3_1/text()" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>0</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</VAR_1_1>

人:

<VAR_1_1>
    <xsl:variable name="g47" select="../*[starts-with(local-name(.), 'G_47')][text() = '1010']" />
    <xsl:value-of select="$g47" />
    <xsl:if test="not($g47)">0</xsl:if>
</VAR_1_1>

(未测试的)

如果可以切换到XSLT 2.0,谓词可以使用正则表达式,而不是starts-with,即:matches(local-name(), 'G_47_[0-9]+_1')

更新(在您的问题更新后)

  

每个块可以分配给G_47 _ * _ 1元素中的一个代码2010 3010或5010

在您的应用模板中,添加xsl:with-param,然后在匹配的模板中添加xsl:param。将三个xsl:apply-templates改为2010,3010,5010。

  

此代码的顺序可能不同,并非所有代码都可以存在(例如,G_47_1_1中只有2010年,G_47_1_1中有5010,G_47_2_1中有5010)

这与XSLT无关,除非您的意思是希望它们排序,在这种情况下您应该添加xsl:sort

  

在目标xml中,我需要填充12个元素(3个块乘4行)

确定。您可能想要动态创建元素名称。使用<xsl:element name="{...}" /> and add the XPath expression that creates the element name in the place of the dots. Have a look at the functions substring-before and substring-after . In XSLT 2.0, simply use a regular expression with replace()`。

  

修复了这些元素的顺序(2010年4个元素,3010之后,5010之后)

使用三种apply-templates方法解决了这个问题,请参见上面的第一点。

  

即使源XML中没有这样的元素,它们也会出现

如果元素为空,则由上面示例代码中的xsl:if修复。如果元素不存在,通常更容易进行双向变换:首先是结构,然后填写缺失的部分。在XSLT 1.0中,您将需要exslt:node-set函数,在XSLT 2.0中,您可以简单地重新应用于第一个转换的临时结果集。所有都在同一个样式表中。请注意在案例名称与原始来源匹配时切换模式。