使用 xslt 1.0 从两个不同的父标签中查找不同的元素
Posted
技术标签:
【中文标题】使用 xslt 1.0 从两个不同的父标签中查找不同的元素【英文标题】:finding distinct elements from two different parent tags using xslt 1.0 【发布时间】:2018-08-25 10:28:45 【问题描述】:我试图从以下示例 XML 中仅使用 XSLT 1.0 从两个不同的父节点中查找不同的值。我需要的是一个模板,它通过将整体作为参数传递给每个<one>
节点来调用。
<vln>
标识每个 <one>
节点
输入:
<?xml version="1.0" encoding="UTF-8"?>
<filename>
<root>
<vln>56837073</vln>
<one>
<vln>1233213427</vln>
<Maddress>
<address>
<state>ak</state>
</address>
</Maddress>
<Maddress>
<address>
<state>vr</state>
</address>
</Maddress>
<co>
<Maddress>
<address>
<state>fg</state>
</address>
</Maddress>
<Maddress>
<address>
<state>ak</state>
</address>
</Maddress>
</co>
</one>
<one>
<vln>6785475239</vln>
<Maddress>
<address>
<state>pp</state>
</address>
</Maddress>
<Maddress>
<address>
<state>fg</state>
</address>
</Maddress>
<co>
<Maddress>
<address>
<state>fg</state>
</address>
</Maddress>
<Maddress>
<address>
<state>ak</state>
</address>
</Maddress>
</co>
</one>
</root>
</filename>
输出: 1.ak、vr、fg
2.pp, fg, ak
3....继续取决于<one>
节点的数量
我按照各种教程尝试了所有我理解的方法。我所取得的成就是使用http://www.jenitennison.com/xslt/grouping/muenchian.html 找到单个父级的不同值,但是当结合起来我不知道。帮我解决这个问题。
我的代码:
<xsl:key name="product" match="one/Maddress/address/state/text()" use="." />
<xsl:template match="one">
<xsl:for-each select="one/Maddress/address/state/text()[generate-id() = generate-id(key('product',.)[1])]">
<xsl:value-of select="."/>
<text> </text>
</xsl:for-each>
<xsl:key name="product2" match="one/co/Maddress/address/state/text()" use="." />
<xsl:template match="two">
<xsl:for-each select="one/co/Maddress/address/state/text()[generate-id() = generate-id(key('product2',.)[1])]">
<xsl:value-of select="."/>
<text> </text>
</xsl:for-each>
这里调用一个和两个模板来检查来自两个不同父节点的不同值。 实现的输出:
1.ak、vr、fg、ak 2.pp, fg, fg, ak
【问题讨论】:
您能否编辑您的问题以显示您尝试过的内容?谢谢! 您的要求是文本格式吗? @AmrendraKumar,不是文本格式 我正在检查纯 HTML 格式的不同值,只是将 XML 简单转换为 HTML @TimC 这是我为从不同的父标签获取不同值所做的工作 【参考方案1】:您正在尝试为每个 one
元素获取不同的状态。这意味着您需要使用连接键
<xsl:key name="product" match="state" use="concat(ancestor::one/vln, '|', .)" />
这假设 vln
对于每个 one
节点都是唯一的。
然后,在每个 one
节点中,您会得到如下不同的状态:
<xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:key name="product" match="state" use="concat(ancestor::one/vln, '|', .)" />
<xsl:template match="/*">
<xsl:apply-templates select="root/one" />
</xsl:template>
<xsl:template match="one">
<xsl:value-of select="vln" />
<xsl:text> </xsl:text>
<xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
【讨论】:
感谢您的回答,它确实有效我错过了这个祖先::one/vln 部分,只是写了 one/vln【参考方案2】:如果您的要求是文本,那么您可以使用以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:value-of select="distinct-values(//state)" separator=", "/>
</xsl:template>
</xsl:stylesheet>
【讨论】:
对不起,我的错误更不用说我只能使用 XSLT 1.0以上是关于使用 xslt 1.0 从两个不同的父标签中查找不同的元素的主要内容,如果未能解决你的问题,请参考以下文章