xsl:if或xsl:apply模板哪个具有更好的内存使用率

时间:2013-04-19 10:57:43

标签: xslt xslt-2.0

让我们说我有一个像下面这样的输入。

<country>
    <name>countryname</name>
    <capital>captialname</capital>
    <population>19000</population>
</country>

我正在尝试使用xsl来表示元素名称。有时可能不会出现国家的儿童元素。所以我可以按如下方式编写我的转换。

<xsl:template match="country">
    <xsl:element name="COUNTRY">
        <xsl:apply-templates select="name" />
        <xsl:apply-templates select="capital" />
        <xsl:apply-templates select="population" />
    </xsl:element>
</xsl:template>

<xsl:template match="name">
    <xsl:element name="NAME">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

<xsl:template match="capital">
    <xsl:element name="CAPITAL">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

<xsl:template match="population">
    <xsl:element name="POPULATION">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

或者我可以这样做。

<xsl:template match="country">
<xsl:element name="COUNTRY">
    <xsl:if test="name">
        <xsl:element name="NAME">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:if>
    <xsl:if test="capital">
        <xsl:element name="CAPITAL">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:if>
    <xsl:if test="population">
        <xsl:element name="POPULATION">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:if>
</xsl:element>

我想知道哪种方式使用更少的内存。我的实际代码大约在模板内七层。所以我需要知道的是,如果我不使用简单元素的使用模板将改善内存使用。

2 个答案:

答案 0 :(得分:1)

根据我的理解,第一个是好的。只需改变:

<xsl:apply-templates select="name" />
        <xsl:apply-templates select="capital" />
        <xsl:apply-templates select="population" />

<xsl:apply-templates/>

只是并且不担心子元素,如果他们不来,有时XSLT会照顾它。

答案 1 :(得分:0)

我认为你正在接近错误的方式。您当前的XSLT模板不是很灵活。对于要添加的新元素,您可能会对其进行修改。

相反,你应该使用身份变换,并包括一个匹配任何通用元素的模板,将名称作为大写。

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="@*|node()[not(self::*)]">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{upper-case(local-name())}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

请注意,以下模板匹配任何元素并将名称转换为大写

<xsl:template match="*">

而另一个模板匹配将匹配属性或除元素之外的任何其他节点,而只是按原样复制它们

<xsl:template match="@*|node()[not(self::*)]">

请注意,如果XML已定义了名称空间,则此解决方案将无效,但不需要进行太多调整即可应对。