使用 XSLT 1.0 合并来自源 xml 和变量的值
Merging values from source xml and variable using XSLT 1.0
我有两个转换输入。
一个是来源 XML source.xml
看起来像这样:
<ROOT>
<row>
<id>1</id>
<value>FooBar</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
<row>
<id>3</id>
<value>FooFoo</value>
</row>
</ROOT>
另外一个是通过参数(<xsl:param name="input" />
)提供给转换的。结构与上面的 XML 相同。但包含不同的行数和不同的值。
<ROOT>
<row>
<id>1</id>
<value>Foo</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
</ROOT>
现在我需要合并这些输入。我想遍历 source.xml
并为每一行的 id 决定变量和更新中是否有相同的 id。如果变量 $input
中的 ID 不同,我想创建新行。
换句话说:source.xml
代表新数据,而输入参数代表我已有的数据。我希望他们合并。我想你明白了。
我尝试了很多方法来解决这个问题,但我总是坚持比较 id 和创建不必要的行。限制是:
- XSLT 1.0 限制。
- 用于比较的输入只能使用 XSLT 参数导入。
输出应如下所示:
<ROOT>
<row>
<id>1</id>
<value>FooBar</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
<row>
<id>3</id>
<value>FooFoo</value>
</row>
</ROOT>
如果提供的参数确实是一个节点集,那么你可以这样做:
XSLT 1.0
<xsl:stylesheet version="1.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="*"/>
<xsl:param name="input" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ROOT">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="$input/ROOT/row[not(id = current()/row/id)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有两个转换输入。
一个是来源 XML source.xml
看起来像这样:
<ROOT>
<row>
<id>1</id>
<value>FooBar</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
<row>
<id>3</id>
<value>FooFoo</value>
</row>
</ROOT>
另外一个是通过参数(<xsl:param name="input" />
)提供给转换的。结构与上面的 XML 相同。但包含不同的行数和不同的值。
<ROOT>
<row>
<id>1</id>
<value>Foo</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
</ROOT>
现在我需要合并这些输入。我想遍历 source.xml
并为每一行的 id 决定变量和更新中是否有相同的 id。如果变量 $input
中的 ID 不同,我想创建新行。
换句话说:source.xml
代表新数据,而输入参数代表我已有的数据。我希望他们合并。我想你明白了。
我尝试了很多方法来解决这个问题,但我总是坚持比较 id 和创建不必要的行。限制是:
- XSLT 1.0 限制。
- 用于比较的输入只能使用 XSLT 参数导入。
输出应如下所示:
<ROOT>
<row>
<id>1</id>
<value>FooBar</value>
</row>
<row>
<id>2</id>
<value>Bar</value>
</row>
<row>
<id>3</id>
<value>FooFoo</value>
</row>
</ROOT>
如果提供的参数确实是一个节点集,那么你可以这样做:
XSLT 1.0
<xsl:stylesheet version="1.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="*"/>
<xsl:param name="input" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ROOT">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="$input/ROOT/row[not(id = current()/row/id)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>