我的xslt代码存在性能问题: 这是我的输入文件:
<?xml version="1.0" encoding="UTF-8"?>
<Products>
<Product ID="111111" Type="Item" ParentID="7402">
<Name>ABC</Name>
<Values>
<Value AttributeID="11">8.00</Value>
<Value AttributeID="12">8.00</Value>
<Value AttributeID="13">0.18</Value>
</Values>
<Product ID="B582B65D" Type="UID" ParentID="111111">
<Values>
<Value AttributeID="11">8.00</Value>
<Value AttributeID="12">8.00</Value>
<Value AttributeID="13">0.18</Value>
<Value AttributeID="14">0.18</Value>
</Values>
</Product>
</Product>
<Product ID="222222" Type="Item" ParentID="7402">
<Name>XYZ</Name>
<Values>
<Value AttributeID="12">8.00</Value>
<Value AttributeID="13">8.00</Value>
<Value AttributeID="15">0.18</Value>
</Values>
<Product ID="B582B65D" Type="UID" ParentID="111111">
<Values>
<Value AttributeID="11">8.00</Value>
<Value AttributeID="12">8.00</Value>
<Value AttributeID="16">0.18</Value>
<Value AttributeID="18">0.18</Value>
</Values>
</Product>
</Product>
</Products>
这是我的转换代码:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math"
extension-element-prefixes="math">
<xsl:output method="xml" indent="yes" />
<xsl:param name="file2" select="document('Mapping.xml')" />
<xsl:template match="/Products">
<Products>
<xsl:for-each select="Product">
<xsl:call-template name="item" />
</xsl:for-each>
</Products>
</xsl:template>
<xsl:template name="item">
<Product type="{./@Type}" ID="{./@ID}">
<xsl:for-each select="./Values/Value">
<xsl:variable name="Idval" select="@AttributeID" />
<xsl:element name="{$file2//Groups/AttributeID[@ID=$Idval]/@group}">
<xsl:element name="{$file2//Groups/AttributeID[@ID=$Idval]}">
<xsl:attribute name="ID"><xsl:value-of select="$Idval"/></xsl:attribute>
<xsl:value-of select="." />
</xsl:element>
</xsl:element>
</xsl:for-each>
<xsl:call-template name="uid" />
</Product>
</xsl:template>
<xsl:template name="uid">
<Product type="{./Product/@Type}" ParentId="{./Product/@ParentID}">
<xsl:for-each select="./Product/Values/Value">
<xsl:variable name="Idval" select="@AttributeID" />
<xsl:element name="{$file2//Groups/AttributeID[@ID=$Idval]/@group}">
<xsl:element name="{$file2//Groups/AttributeID[@ID=$Idval]}">
<xsl:attribute name="ID"><xsl:value-of select="$Idval"/></xsl:attribute>
<xsl:value-of select="." />
</xsl:element>
</xsl:element>
</xsl:for-each>
</Product>
</xsl:template>
</xsl:stylesheet>
以上xslt使用下面的xml文件将属性id映射到相应的名称和组 Mapping.xml
<?xml version="1.0" encoding="UTF-8"?>
<Groups>
<AttributeID ID="11" group="Pack1">Height</AttributeID>
<AttributeID ID="12" group="Pack2">Width</AttributeID>
<AttributeID ID="13" group="Pack1">Depth</AttributeID>
<AttributeID ID="14" group="Pack3">Length</AttributeID>
<AttributeID ID="15" group="Pack3">Lbs</AttributeID>
<AttributeID ID="16" group="Pack4">Litre</AttributeID>
</Groups>
答案 0 :(得分:4)
替换
等表达式的使用select="$file2//Groups/AttributeID[@ID=$Idval]"
带钥匙:
<xsl:key name="ID" match="Groups/AttributeID" use="@ID"/>
然后
select="key('ID', $IDval, $file)"/>
另外,Saxon-EE会自动为您进行优化。
带有3个参数的key()函数是XSLT 2.0语法。如果您不幸使用XSLT 1.0,则必须编写一个虚拟xsl:for-each,使$ file成为上下文项,因为key()只会在包含上下文项的文档中进行选择。
答案 1 :(得分:1)
为交叉文档查找定义一个键:<xsl:key name="by-id" match="Groups/AttributeID" use="@ID"/>
,然后(假设一个XSLT 2.0处理器),您可以简化<xsl:element name="{$file2//Groups/AttributeID[@ID=$Idval]/@group}">
到<xsl:element name="{key('by-id', @AttributeID, $file2)/@group">
之类的表达式。对您拥有的其他交叉引用进行相同的更改,即所有$file2//Groups/AttributeID[@ID=$Idval]
表达式都应使用键查找。
答案 2 :(得分:0)
简化假设您的第二个文件不是太大,您希望将值折叠到模板中。它也适用于XSLT 1.0。像这样:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math"
extension-element-prefixes="math">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<Products>
<xsl:apply-templates select="/Products/Product" />
</Products>
</xsl:template>
<xsl:template match="Product">
<xsl:element name="Product">
<xsl:apply-templates select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="Name">
<Name>
<xsl:value-of select="." />
</Name>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="Values">
<Values>
<xsl:apply-templates />
</Values>
</xsl:template>
<!-- Templates for individual AttributeIDs, only when there are few -->
<xsl:template match="Value[@AttributeID='11']">
<Pack1>
<xsl:element name="Height">
<xsl:attribute name="ID">
<xsl:value-of select="@AttributeID" />
</xsl:attribute>
<xsl:value-of select="." />
</xsl:element>
</Pack1>
</xsl:template>
<!-- Repeat for the other AttributeID values -->
</xsl:stylesheet>
(键入我的头,将包含拼写错误)
当然,如果它很大,迈克尔的建议是最好的行动方案。