XSLT 1.0 - 连接已知子节点,按未知父节点分组 [英] XSLT 1.0 - Concatenate known child nodes, group by unknown parent
问题描述
我要变身
<entry>
<parent1>
<object_id>1580</object_id>
</parent1>
<parent1>
<object_id>1586</object_id>
</parent1>
<parent2>
<object_id>1582</object_id>
</parent2>
<parent2>
<object_id>1592</object_id>
</parent2>
</entry>
进入
<entry>
<parent1>1580-1586</parent1>
<parent2>1582-1592</parent2>
</entry>
顶级条目名称未知.父节点名称未知,具有相同名称的父节点数量可能会有所不同.子节点已知为object_id".
Top-level entry name is unknown. Parent names are unknown, and the number of parent nodes with the same name can vary. Child nodes are known "object_id".
所以,我想以抽象的方式对未知的父节点进行分组,并连接子节点值,以-"分隔.
So, I would like to group the unknown parents in an abstract way, and concatenate child node values, delimited by "-".
使用 XSLT 合并 XML 节点接近回答问题,分组/合并相同节点的子节点也是如此在 xml/xslt 中,但它们并不是我所需要的.
Merge XML nodes using XSLT comes close to answering the question, as does Group/merge childs of same nodes in xml/xslt , but they're not quite what I need.
到目前为止我有:
<xsl:key name="groupName" match="*[object_id]" use="."/>
<xsl:template match="*[generate-id(.) = generate-id(key('groupName', .))]">
<xsl:copy>
<xsl:call-template name="join">
<xsl:with-param name="list" select="object_id" />
<xsl:with-param name="separator" select="'-'" />
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="join">
<xsl:param name="list" />
<xsl:param name="separator"/>
<xsl:for-each select="$list">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:value-of select="$separator" />
</xsl:if>
</xsl:for-each>
</xsl:template>
提前致谢!
推荐答案
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kObjByValAndParent" match="object_id"
use="name(..)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*"/>
<xsl:template priority="2" match=
"/*/*[generate-id(object_id)
=
generate-id(key('kObjByValAndParent',name())[1])
]
">
<xsl:copy>
<xsl:value-of select=
"concat(object_id, ' - ',
key('kObjByValAndParent',name())[last()]
)
"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<entry>
<parent1>
<object_id>1580</object_id>
</parent1>
<parent1>
<object_id>1586</object_id>
</parent1>
<parent2>
<object_id>1582</object_id>
</parent2>
<parent2>
<object_id>1592</object_id>
</parent2>
</entry>
产生想要的、正确的结果:
<entry>
<parent1>1580 - 1586</parent1>
<parent2>1582 - 1592</parent2>
</entry>
说明:
正确使用和覆盖身份规则强>.
正确使用慕尼黑分组方法.
<小时>
二.如果必须将所有值连接在一起,请使用此稍微修改的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kObjByValAndParent" match="object_id"
use="name(..)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*"/>
<xsl:template priority="2" match=
"/*/*[generate-id(object_id)
=
generate-id(key('kObjByValAndParent',name())[1])
]
">
<xsl:copy>
<xsl:for-each select="key('kObjByValAndParent',name())">
<xsl:if test="not(position()=1)"> - </xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这篇关于XSLT 1.0 - 连接已知子节点,按未知父节点分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!