带有元素内容的XSL过滤器

时间:2013-06-27 15:01:17

标签: xml xslt xpath xml-parsing

我正在尝试优化xsl,因为修改数据需要很长时间。

我的sourcedata(我无法修改)看起来像:

<catalog>
    <product>
        <prodid>12345</prodid>
        .....
    </proudct>
    <product_group_map>
       <prodid>12345</prodid>
       <groupid>2435</groupid>
    </product_group_map>
</catalog>

我想让这些groupId与产品一起使用。到目前为止我所做的事情看起来像这样:

<xsl:variable name="id"><xsl:value-of select="prodid"/></xsl:variable>

<xsl:variable name="grId">
    <xsl:for-each select="../product_group_map">
        <xsl:if test="prodid = $id">
            <xsl:value-of select="groupid"/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

<!-- the actual print of the values -->
<xsl:value-of select="concat( $id, $separator, $grId)"/>

因此该过程运行O ^ 2。对于700万件不合适的产品。有没有办法在其他地方匹配所需的groupId? 我想到如下:如果xml看起来像这样

<catalog>
    <product>
        <prodid>12345</prodid>
        .....
    </proudct>
    <product_group_map prodId="12345">
       <groupid>2435</groupid>
    </product_group_map>
</catalog>

我可以使用这样的选择:

<!--allready in product with the path -->
<xsl:variable name="id"><xsl:value-of select="prodid"/></xsl:variable>
<xsl:variable name="groupid"><xsl:value-of select="../product_group_map[@prodid = $prodId]/groupid"/></xsl:variable>

1 个答案:

答案 0 :(得分:2)

首先,让xsl:variable只包含value-of是低效的,您最好将选择表达式放在xsl:variable本身上。其次,您可以使用当前设置为prodid是元素

的属性做同样的建议
<xsl:variable name="groupid" select="../product_group_map[prodid = $id]/groupid" />

但定义密钥(在任何模板之外)

可能更有效
<xsl:key name="groupByProduct" match="prod_group_map/groupid" use="../prodid" />

然后您只需使用

即可找到群组ID
<xsl:variable name="groupid" select="key('groupByProduct', $id)" />

请注意,如果相同的prodid通过不同的product_group_map元素链接到多个不同的组ID,则生成的$groupid变量将是包含所有匹配{{1}的节点集元素。