我有以下模板:
<xsl:template match="footnote">
<xsl:variable name = "string">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:variable name = "bool">
<xsl:if test="$string = preceding-sibling::node()/$string">
<xsl:text>false</xsl:test>
</xsl:if>
</xsl:variable>
<xsl:if test="$bool != 'false'">
<!-- DO STUFF -->
</xsl:if>
</xsl:template>
我正在尝试检查当前节点的$ string变量,并针对所有以前的脚注节点进行检查,看看它们是否具有相同的$ string变量。如果它与任何前面的兄弟姐妹不匹配那么它应该做的东西,否则它什么都不做。
使用我的代码,测试“$ string = preceding-sibling :: node()/ $ string”总是计算为true,即使还没有创建脚注节点。
任何人都可以帮助我吗?我很难创建表达式来与之前所有兄弟姐妹中的变量进行比较。
编辑:示例XML:
<xml>
<footnote>Footnote 1</footnote>
<footnote>Footnote 2</footnote>
<footnote>Footnote 1</footnote>
<footnote>Footnote 1</footnote>
<footnore>Footnote 3</footenote>
</xml>
我正在尝试将其转换为:
<xml>
<footnote>Footnote 1</footnote>
<footnote>Footnote 2</footnote>
<footnote>Footnore 3</footnore>
</xml
答案 0 :(得分:4)
好。发布您的输出XML使其更清晰!你带着解决方案:
示例XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<footnote>Matching</footnote>
<footnote>Example1</footnote>
<footnote>Matching</footnote>
<footnote>Example2</footnote>
<footnote>Example3</footnote>
</root>
和XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="footnote[.=preceding-sibling::footnote/.]"/>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<footnote>Matching</footnote>
<footnote>Example1</footnote>
<footnote>Example2</footnote>
<footnote>Example3</footnote>
</xml>
答案 1 :(得分:1)
假设您想针对前一个脚注text()
检查当前脚注text()'s
的值是否唯一,那么您只需查看preceding-sibling::node()'s text()
:
<xsl:if test="$string = preceding-sibling::node()/text()">
e.g。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
>
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />
<xsl:template match="/xml">
<xml>
<xsl:apply-templates select="footnote" />
</xml>
</xsl:template>
<xsl:template match="footnote">
<xsl:variable name = "string">
<xsl:value-of select="./text()"/>
</xsl:variable>
<xsl:variable name = "bool">
<xsl:if test="$string = preceding-sibling::node()/text()">
<xsl:text>false</xsl:text>
</xsl:if>
</xsl:variable>
<xsl:if test="$bool != 'false'">
<xsl:copy-of select="."></xsl:copy-of>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将转动输入:
<xml>
<footnote>
someVal
</footnote>
<footnote>
anotherVal
</footnote>
<footnote>
anotherVal
</footnote>
<footnote>
newVal
</footnote>
</xml>
分为:
<xml>
<footnote>
someVal
</footnote>
<footnote>
anotherVal
</footnote>
<footnote>
newVal
</footnote>
</xml>
如果您的目的是识别元素内的群体,您还应该查看Muenchian分组。
答案 2 :(得分:1)
您可以使用
<xsl:template match="footnote[not(. = preceding-sibling::footnote)]">
创建一个模板,仅触发给定脚注字符串的第一个实例。如果此节点的字符串值与其先前兄弟节点的任何的字符串值相同,则. = preceding-sibling::footnote
为true,因此如果{em}与not(....)将为true >所有。
但是对于大型文档而言,这将是相当低效的(脚注元素的数量是二次的)。更好的方法是使用<xsl:for-each-group>
(XSLT 2.0)或Muenchian Grouping(XSLT 1.0)按照字符串值对footnote
元素进行分组,并从每个组中提取第一个元素。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="fn" match="footnote" use="." />
<!-- Ignore all but the first footnote for a given value -->
<xsl:template match="footnote[generate-id() != generate-id(key('fn', .)[1])]" />
<!-- copy everything else verbatim -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 3 :(得分:0)
<xsl:template match="footnote">
<xsl:variable name = "string">
<xsl:value-of select="./text()"/>
</xsl:variable>
<xsl:variable name = "bool">
<xsl:if test="$string != preceding-sibling::node()/text()">
<xsl:text>false</xsl:text>
</xsl:if>
</xsl:variable>
<xsl:if test="$bool != 'false'">
true
</xsl:if>
<xsl:if test="$bool = 'false'">
false
</xsl:if>
</xsl:template>
答案 4 :(得分:0)
在XSLT 2.0中,您有一个distinct-values函数:
<xsl:for-each select="distinct-values(footnote)">
<footnote><xsl:value-of select="."/></footnote>
</xsl:for-each>