Xslt 3.0 检查xml文件,并使用xslt-3生成关于重复元素的报告
给定以下xml作为输入,我尝试使用xslt-3创建一个报告Xslt 3.0 检查xml文件,并使用xslt-3生成关于重复元素的报告,xslt-3.0,Xslt 3.0,给定以下xml作为输入,我尝试使用xslt-3创建一个报告 <breakfast_menu> <food> <name>01</name> <price>$5.95</price> <description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</desc
<breakfast_menu>
<food>
<name>01</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</description>
<calories>650</calories>
</food>
<food>
<name>01</name>
<price>$7.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</description>
<calories>350</calories>
</food>
<food>
<name>02</name>
<price>$8.95</price>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>03</name>
<price>$4.50</price>
<description>Thick slices made from our homemade sourdough bread</description>
</food>
<food>
<name>04</name>
<price>$6.95</price>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>100</calories>
</food>
<food>
<name>05</name>
<price>$7.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</description>
<calories>250</calories>
</food>
</breakfast_menu>
我使用xsl v2的试用版:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:key name="ids" match="*[@description]" use="@description"/>
<xsl:template match="/">
<duplicates>
<xsl:apply-templates select="//*[@description]"/>
</duplicates>
</xsl:template>
<xsl:template match="*[@description]">
<xsl:if test="count(key('ids', @description)) > 1">
<duplicate
id="{@description}"
dup-count="{count(key('ids', @description))}"
node-xpath="{string-join((for $node in ancestor::* return concat($node/name(),'[', count($node/preceding-sibling::*[name() = $node/name()])+1, ']'),concat(name(),'[', count(preceding-sibling::*[name() = current()/name()]) + 1, ']')
),'/')}">
</duplicate>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
您可以对每个组使用
,
到分组依据=“说明”
,然后您可以使用分隔符=“ ;”的值输出文本格式:
您想要的输出格式似乎是纯文本,但是XSLT创建了一个XML文档,其中包含一个duplicates
根元素,然后是仅具有属性的duplicate
子元素。当您说您使用XSLT 2并希望使用XSLT 3时,您并不是对每个组使用,
来识别重复项,而是一个键。此外,您说您希望按说明
对重复项进行排序,但在以灯
开头的项之前,有以两个
开头的项。因此,你需要澄清你的要求。一个小的修改,怎么可能在报告中,比如在第一行,有一个数字表示多次找到的描述的数量?在上面的问题中,结果是3我不确定你提到的3
与什么有关。如果要输出组中的项目,可以使用count(current-group())
,就像我在
中所做的那样。如果这没有帮助,那么问一个新问题。不,我需要的只是一个数字,类似于找到的所有组,求和(count(current-group())-1)。该总和将输出每个描述出现多次的次数,因此在上述示例中,结果为3。请提出一个新问题,如果要计算或汇总所有组,需要先以某种方式存储分组结果,这当然是可能的,但不属于对这个问题的评论。你是对的,我的错误:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:key name="ids" match="*[@description]" use="@description"/>
<xsl:template match="/">
<duplicates>
<xsl:apply-templates select="//*[@description]"/>
</duplicates>
</xsl:template>
<xsl:template match="*[@description]">
<xsl:if test="count(key('ids', @description)) > 1">
<duplicate
id="{@description}"
dup-count="{count(key('ids', @description))}"
node-xpath="{string-join((for $node in ancestor::* return concat($node/name(),'[', count($node/preceding-sibling::*[name() = $node/name()])+1, ']'),concat(name(),'[', count(preceding-sibling::*[name() = current()/name()]) + 1, ']')
),'/')}">
</duplicate>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:output method="text" />
<xsl:template match="breakfast_menu">
<xsl:for-each-group select="food" group-by="description">
<xsl:sort select="current-grouping-key()"/>
<xsl:if test="current-group()[2]">
<xsl:apply-templates select="current-group()"/>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="food">
<xsl:value-of select="name, description, string(calories)" separator="	"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>