我有一个类似于以下内容的xml行集:
<root>
<dataset1>
<rows>
<row id="0" title="Some Title" lookupValues="1;#Something1;#2;#Something2"/>
<row id="1" title="Some other title" lookupValues="1;#Something1;#3;#Something3"/>
</rows>
</dataset1>
<dataset2>
<rows>
<row id="1" lookupValue="Something1" anotherValue="ThisOne"/>
<row id="2" lookupValue="Something2" anotherValue="ThatOne"/>
<row id="3" lookupValue="Something3" anotherValue="TheOtherOne"/>
<row id="4" lookupValue="Not Something"/>
</rows>
</dataset2>
</root>
我正在尝试转换为更像以下格式的格式:
<newroot>
<rows>
<row uniqueid="1" id="0" title="Some Title" lookupValue="Something1" anotherValue="ThisOne"/>
<row uniqueid="2" id="0" title="Some Title" lookupValue="Something2" anotherValue="ThatOne"/>
<row uniqueid="3" id="1" title="Some other title" lookupValue="Something1" anotherValue="ThisOne"/>
<row uniqueid="4" id="1" title="Some other title" lookupValue="Something3" anotherValue="TheOtherOne"/>
</rows>
</newroot>
注意重复的行;这是应用程序的要求。还要注意 丢弃错过的lookupValue行。
有没有人知道实现这种转变的真正有效方式?
感谢。
更新:我应该更清楚我想要完成的事情。我添加了一些信息,以更好地说明我正在寻找的合并类型。
更新2:除了原始数据集中存在错误外,给出的答案可能有效;即lookupValues
属性的格式。分隔符有点不同,因为除了实际的查找文本之外,源XML还包含索引号。
答案 0 :(得分:0)
除了为每个新行生成唯一的id值之外,这一切都非常简单。为此,我担心,你必须做两次通过:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="dataset2" match="row" use="@lookupValue" />
<xsl:variable name="new-rows">
<xsl:for-each select="/root/dataset1/rows/row">
<xsl:call-template name="generate-rows">
<xsl:with-param name="values" select="@lookupValues"/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<newroot>
<rows>
<xsl:for-each select="exsl:node-set($new-rows)/row">
<xsl:copy>
<xsl:attribute name="uniqueid">
<xsl:value-of select="position()"/>
</xsl:attribute>
<xsl:copy-of select="@*"/>
</xsl:copy>
</xsl:for-each>
</rows>
</newroot>
</xsl:template>
<xsl:template name="generate-rows">
<xsl:param name="values"/>
<xsl:param name="delimiter" select="';'"/>
<xsl:variable name="token" select="substring-before(concat($values, $delimiter), $delimiter)" />
<row id="{@id}" title="{@title}" lookupValue="{$token}" anotherValue="{key('dataset2', $token)/@anotherValue}"/>
<xsl:if test="contains($values, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="generate-rows">
<xsl:with-param name="values" select="substring-after($values, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
鉴于您修改了输入内容,请将generate-rows
模板更改为:
<xsl:template name="generate-rows">
<xsl:param name="values"/>
<xsl:param name="delimiter" select="';#'"/>
<xsl:variable name="token" select="substring-before(substring-after(concat($values, $delimiter), $delimiter), $delimiter)" />
<row id="{@id}" title="{@title}" lookupValue="{$token}" anotherValue="{key('dataset2', $token)/@anotherValue}"/>
<xsl:if test="contains(substring-after($values, $delimiter), $delimiter)">
<!-- recursive call -->
<xsl:call-template name="generate-rows">
<xsl:with-param name="values" select="substring-after(substring-after($values, $delimiter), $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>