这变得越来越复杂了:)
现在我在上一个问题中面临另一个问题,我们设法从一个父节点中获取唯一值
现在:
<?xml version="1.0" encoding="ISO-8859-1"?>
<roots>
<root>
<name>first</name>
<item>
<something>A</something>
<something>A</something>
</item>
<item>
<something>B</something>
<something>A</something>
</item>
<item>
<something>C</something>
<something>P</something>
</item>
<item>
<something>A</something>
<something>L</something>
</item>
<item>
<something>A</something>
<something>A</something>
</item>
<item>
<something>B</something>
<something>A</something>
</item>
<item>
<something>D</something>
<something>A</something>
</item>
</root>
<root>
<name>second</name>
<item>
<something>E</something>
<something>A</something>
</item>
<item>
<something>B</something>
<something>A</something>
</item>
<item>
<something>F</something>
<something>A</something>
</item>
<item>
<something>A</something>
<something>A</something>
</item>
<item>
<something>A</something>
<something>A</something>
</item>
<item>
<something>B</something>
<something>H</something>
</item>
<item>
<something>D</something>
<something>G</something>
</item>
</root>
</roots>
现在我需要获取仅来自一个节点之前的唯一值,但仅取决于第二个位置上的元素
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="text"/>
<xsl:key name="item-by-value" match="something"
use="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/>
<xsl:key name="rootkey" match="root" use="name"/>
<xsl:template match="/">
<xsl:for-each select="key('rootkey','first')">
<xsl:for-each select="item/something[1]">
<xsl:sort />
<xsl:if test="generate-id() = generate-id(key('item-by-value',
concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
<xsl:text>_________</xsl:text>
<xsl:for-each select="item/something[2]">
<xsl:sort />
<xsl:if test="generate-id() = generate-id(key('item-by-value',
concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
使用此XSL我得到ABCD_________LP 我需要的结果是ABCD _________ ALP
任何想法?
答案 0 :(得分:1)
对我之前的问题的回答略有修改,你已经知道了!
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kSomethingByNameAndVal-1" match="something[1]"
use="concat(../../name, '+', .)"/>
<xsl:key name="kSomethingByNameAndVal-2" match="something[2]"
use="concat(../../name, '+', .)"/>
<xsl:template match="/">
<xsl:for-each select="*/*">
<xsl:for-each select=
"item/something[1]
[generate-id()
=
generate-id(key('kSomethingByNameAndVal-1',
concat(../../name, '+', .)
)
)
]
">
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select=
"item/something[2]
[generate-id()
=
generate-id(key('kSomethingByNameAndVal-2',
concat(../../name, '+', .)
)
)
]
">
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时,会生成所需的正确结果:
ABCD
APL
EBFAD
AHG
答案 1 :(得分:1)
问题再一次是,如果你想说“在item
节点中此位置出现此根的第一个节点”,那么你必须将“item
节点中的位置”添加到密钥。您可以通过使用两个单独的密钥来完成此操作,如Dimitre的解决方案,或将您的密钥更改为:
use="concat(normalize-space(.), ' ',
count(./preceding-sibling::something), ' ', generate-id(./ancestor::root))"/>
然后让你的两个测试表达式看起来像:
<xsl:if test="generate-id() = generate-id(key('item-by-value',
concat(normalize-space(.), ' 0 ', generate-id(./ancestor::root))))">
和
<xsl:if test="generate-id() = generate-id(key('item-by-value',
concat(normalize-space(.), ' 1 ', generate-id(./ancestor::root))))">
答案 2 :(得分:0)
我知道你受限于XSLT 1.0并且你正在使用Xalan,但是我将添加这个答案,以防万一它可能会帮助别人在将来进行搜索。 (那可以使用XSLT 2.0。)希望你不介意。
另外,我使用Saxon-HE 9.2.0.6作为处理器。
这是样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text"/>
<xsl:template match="/roots">
<xsl:for-each select="root">
<xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
以下是使用XML的输出:
A B C D___A P L
E B F A D___A H G
如果要从输出中去除空格,可以将输出放在变量中,然后使用replace
去除空格。 (任何人都知道更好的方法吗?)
样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text"/>
<xsl:template match="/roots">
<xsl:variable name="output">
<xsl:for-each select="root">
<xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="replace($output,' ','')"/>
</xsl:template>
</xsl:stylesheet>
输出:
ABCD___APL
EBFAD___AHG