通过复制和访问祖先来预先计算节点集 (XSLT 1.0)
precalculating node-set via copy-of and accessing ancestors (XSLT 1.0)
我想预先计算源 XML 中节点的子树,并分别处理它们(因为我希望以不同的方式处理子集),并访问祖先的一些值。
简单的例子
<numbers count="5">
<number value="1"/>
<number value="2"/>
<number value="3"/>
<number value="4"/>
<number value="5"/>
</numbers>
假设我有一个 xslt (MSXML) 以某种方式提取偶数节点
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<evens>
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<even>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
</even>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
我们得到..
<evens>
<even count="5" value="2" />
<even count="5" value="4" />
</evens>
不错...
但是我怎样才能将过滤与处理分开,比如...
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="calculateNodes">
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="nodes">
<xsl:call-template name="calculateNodes"/>
</xsl:variable>
<evens>
<xsl:for-each select="msxsl:node-set($nodes)/number">
<even>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
</even>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
这给出了。
<evens>
<even count="" value="2" />
<even count="" value="4" />
</evens>
所以...祖先没有被复制。
有没有惯用的方法来摆脱这个?
复制的节点独立存在于原始树之外。在您的示例中,number
的父级是 $nodes
变量,它没有任何属性。
你为什么不简单地做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/numbers">
<xsl:variable name="nodes" select="number[@value mod 2 = 1]"/>
<evens>
<xsl:for-each select="$nodes">
<even count="{../@count}" value="{@value}"/>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
这样你就有了一个包含对原始节点的 reference 的变量,而不是 copy。然后您还可以访问原始父级。并且变量的内容是一个节点集;你不需要转换它。
这似乎有效
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="calculateNodes">
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<numberWrapper>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:copy-of select="."/>
</numberWrapper>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="nodes">
<xsl:call-template name="calculateNodes"/>
</xsl:variable>
<evens>
<xsl:for-each select="msxsl:node-set($nodes)/numberWrapper">
<even>
<xsl:attribute name="count">
<xsl:value-of select="@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="number/@value"/>
</xsl:attribute>
</even>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
我想预先计算源 XML 中节点的子树,并分别处理它们(因为我希望以不同的方式处理子集),并访问祖先的一些值。
简单的例子
<numbers count="5">
<number value="1"/>
<number value="2"/>
<number value="3"/>
<number value="4"/>
<number value="5"/>
</numbers>
假设我有一个 xslt (MSXML) 以某种方式提取偶数节点
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<evens>
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<even>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
</even>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
我们得到..
<evens>
<even count="5" value="2" />
<even count="5" value="4" />
</evens>
不错...
但是我怎样才能将过滤与处理分开,比如...
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="calculateNodes">
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="nodes">
<xsl:call-template name="calculateNodes"/>
</xsl:variable>
<evens>
<xsl:for-each select="msxsl:node-set($nodes)/number">
<even>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
</even>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
这给出了。
<evens>
<even count="" value="2" />
<even count="" value="4" />
</evens>
所以...祖先没有被复制。
有没有惯用的方法来摆脱这个?
复制的节点独立存在于原始树之外。在您的示例中,number
的父级是 $nodes
变量,它没有任何属性。
你为什么不简单地做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/numbers">
<xsl:variable name="nodes" select="number[@value mod 2 = 1]"/>
<evens>
<xsl:for-each select="$nodes">
<even count="{../@count}" value="{@value}"/>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>
这样你就有了一个包含对原始节点的 reference 的变量,而不是 copy。然后您还可以访问原始父级。并且变量的内容是一个节点集;你不需要转换它。
这似乎有效
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="calculateNodes">
<xsl:for-each select="numbers/number">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<numberWrapper>
<xsl:attribute name="count">
<xsl:value-of select="../@count"/>
</xsl:attribute>
<xsl:copy-of select="."/>
</numberWrapper>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="nodes">
<xsl:call-template name="calculateNodes"/>
</xsl:variable>
<evens>
<xsl:for-each select="msxsl:node-set($nodes)/numberWrapper">
<even>
<xsl:attribute name="count">
<xsl:value-of select="@count"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="number/@value"/>
</xsl:attribute>
</even>
</xsl:for-each>
</evens>
</xsl:template>
</xsl:stylesheet>