使用XSLT 2.0,我试图在以下文档中创建给定元素的所有子元素之间的关系列表:
<doc>
<part1>
<name>John</name>
<name>Paul</name>
<name>George</name>
<name>Ringo</name>
<place>Liverpool</place>
</part1>
<part2>
<name>Romeo</name>
<name>Romeo</name>
<name>Juliet</name>
<fam>Montague</fam>
<fam>Capulet</fam>
</part2>
</doc>
我想获得的结果,理想情况是通过混淆和权衡相同的关系,将是(以任何顺序)类似的东西:
<doc>
<part1>
<rel><name>John</name><name>Paul</name></rel>
<rel><name>John</name><name>George</name></rel>
<rel><name>John</name><name>Ringo</name></rel>
<rel><name>Paul</name><name>George</name></rel>
<rel><name>Paul</name><name>Ringo</name></rel>
<rel><name>George</name><name>Ringo</name></rel>
<rel><name>John</name><place>Liverpool</place></rel>
<rel><name>Paul</name><place>Liverpool</place></rel>
<rel><name>George</name><place>Liverpool</place></rel>
<rel><name>Ringo</name><place>Liverpool</place></rel>
</part1>
<part2>
<rel weight="2"><name>Romeo</name><name>Juliet</name></rel>
<rel weight="2"><name>Romeo</name><fam>Montague</fam></rel>
<rel weight="2"><name>Romeo</name><fam>Capulet</fam></rel>
<rel><name>Juliet</name><fam>Montague</fam></rel>
<rel><name>Juliet</name><fam>Capulet</fam></rel>
<rel><fam>Montague</fam><fam>Capulet</fam></rel>
</part2>
</doc>
- 但我不确定如何继续。非常感谢您的帮助。
答案 0 :(得分:0)
至少可以使用以下XSLT脚本解决问题的组合部分。它没有解决重复的问题,但可以在第二次转换中完成。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- standard copy template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="doc/*">
<xsl:copy>
<xsl:variable name="l" select="./*"/>
<xsl:for-each select="$l">
<xsl:variable name="a" select="."/>
<xsl:variable name="posa" select="position()"/>
<xsl:variable name="namea" select="name()"/>
<xsl:for-each select="$l">
<xsl:if test="position() > $posa and (. != $a or name() != $namea)">
<rel>
<xsl:copy-of select="$a"/>
<xsl:copy-of select="."/>
</rel>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于示例的第一部分时,会产生:
<part1>
<rel><name>John</name><name>Paul</name></rel>
<rel><name>John</name><name>George</name></rel>
<rel><name>John</name><name>Ringo</name></rel>
<rel><name>John</name><place>Liverpool</place></rel>
<rel><name>Paul</name><name>George</name></rel>
<rel><name>Paul</name><name>Ringo</name></rel>
<rel><name>Paul</name><place>Liverpool</place></rel>
<rel><name>George</name><name>Ringo</name></rel>
<rel><name>George</name><place>Liverpool</place></rel>
<rel><name>Ringo</name><place>Liverpool</place></rel>
</part1>
这似乎是正确的。如果不知道是否可以在同一转换中完成重复消除(或称为加权)。
答案 1 :(得分:0)
你还没有解释这里需要应用的逻辑,所以这很大程度上是基于猜测:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc/*">
<!-- first pass-->
<xsl:variable name="unique-items">
<xsl:for-each-group select="*" group-by="concat(name(), '|', .)">
<item name="{name()}" count="{count(current-group())}" value="{.}"/>
</xsl:for-each-group>
</xsl:variable>
<!-- output -->
<xsl:copy>
<xsl:for-each select="$unique-items/item">
<xsl:variable name="left" select="."/>
<xsl:for-each select="following-sibling::item">
<xsl:variable name="weight" select="$left/@count * @count" />
<rel>
<xsl:if test="$weight gt 1">
<xsl:attribute name="weight" select="$weight"/>
</xsl:if>
<xsl:apply-templates select="$left | ." />
</rel>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:element name="{@name}">
<xsl:value-of select="@value"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这里的想法是在第一遍中删除重复项,然后在第二遍(最终)传递中枚举所有组合。权重的计算方法是将组合对中每个成员的出现次数相乘,并仅在超过1时显示。