通过消除重复代码来优化XSLT代码

时间:2020-10-15 19:39:57

标签: xslt xslt-2.0

此XSLT转换有效,但是我要重复多次相同的代码,这使其非常多余!

如何优化呢?

colspan

谢谢!

3 个答案:

答案 0 :(得分:4)

我想你可以做到:

<xsl:for-each select="RVWT | RVW[not(../RVWT)]">
    <xsl:variable name="rvwt" select="tokenize(., '\|')"/>
    <TextTypeCode>08</TextTypeCode>
    <Text textformat="05">
        <xsl:value-of select="$rvwt[1]"/>
    </Text>
    <TextSourceTitle>
        <xsl:value-of select="normalize-space(substring($rvwt[2], 3))"/>
    </TextSourceTitle>
</xsl:for-each>

答案 1 :(得分:4)

I。我会使用XSLT 2.0可以提供的最好的功能:创建函数

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 
  <xsl:template match="/*">
     <xsl:sequence select=
      "my:Extract(RVW[not(../RVWT)] | RVWT)"/>
  </xsl:template>

  <xsl:function name="my:Extract">
    <xsl:param name="pItems" as="item()+"/>
    <xsl:for-each select="$pItems">
        <xsl:variable name="vItemTokens" select="tokenize(., '\|')"/>
        <TextTypeCode>08</TextTypeCode>
        <Text textformat="05">
            <xsl:value-of select="$vItemTokens[1]"/>
        </Text>
        <TextSourceTitle>
            <xsl:value-of select="normalize-space(substring($vItemTokens[2], 3))"/>
        </TextSourceTitle>
    </xsl:for-each>
  </xsl:function>
</xsl:stylesheet>

在以下XML文档上应用此转换时:

<t>
    <RVWT>a|bbbTail|c</RVWT>
    <RVWT>d|eeeTail|f</RVWT>
    <RVWT>g|hhhTail|i</RVWT>
    
    <RVW>p|qqqTail|r</RVW>
</t>

产生了所需的正确结果

<TextTypeCode>08</TextTypeCode>
<Text textformat="05">a</Text>
<TextSourceTitle>bTail</TextSourceTitle>
<TextTypeCode>08</TextTypeCode>
<Text textformat="05">d</Text>
<TextSourceTitle>eTail</TextSourceTitle>
<TextTypeCode>08</TextTypeCode>
<Text textformat="05">g</Text>
<TextSourceTitle>hTail</TextSourceTitle>

应用于此文档

<t>
    <RVWTX>a|bbbTail|c</RVWTX>
    <RVWTX>d|eeeTail|f</RVWTX>
    <RVWTX>g|hhhTail|i</RVWTX>
    
    <RVW>p|qqqTail|r</RVW>
</t>

再次生成所需的正确结果

<TextTypeCode>08</TextTypeCode>
<Text textformat="05">p</Text>
<TextSourceTitle>qTail</TextSourceTitle>

II。注意

使用这种方法,我们还有一个好处,就是该函数可以接受任何项目序列,而不仅是元素。

例如,可以调用这样的函数

my:Extract(('a|bbbTail|c', 'd|eeeTail|f'))

并仍然得到想要的结果

<TextTypeCode>08</TextTypeCode>
<Text textformat="05">a</Text>
<TextSourceTitle>bTail</TextSourceTitle>
<TextTypeCode>08</TextTypeCode>
<Text textformat="05">d</Text>
<TextSourceTitle>eTail</TextSourceTitle>

答案 2 :(得分:3)

您可以编写模板

<xsl:template match="RVWT | RVW">
    <xsl:variable name="rvwt" select="tokenize(., '\|')"/>
    <TextTypeCode>08</TextTypeCode>
    <Text textformat="05">
        <xsl:value-of select="$rvwt[1]"/>
    </Text>
    <TextSourceTitle>
        <xsl:value-of select="normalize-space(substring($rvwt[2], 3))"/>
    </TextSourceTitle>
</xsl:template>

,然后在父级中处理<xsl:apply-templates select="if (RVWT) then RVWT else RVW"/>