我有以下xml文件:
1) source.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Name><SSTVal>Name</SSTVal></Name>
<Version><SSTVal>Version</SSTVal></Version>
<Messages>
<Message><SSTVal>Message</SSTVal></Message>
</Messages>
</root>
2) values.xml
<?xml version="1.0" encoding="UTF-8"?>
<Values>
<SSTVal name="Name">Test Name</SSTVal>
<SSTVal name="Version">1.2.3</SSTVal>
<SSTVal name="Message">Hello World!</SSTVal>
</Values>
我正在尝试编写一个xslt文件,它搜索第一个文件中出现的每一个SSTVal,并将其替换为第二个文件中匹配的SSTVal的值,因此结果看起来像
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Name>Test Name</Name>
<Version>1.2.3</Version>
<Messages>
<Message>Hello World!</Message>
</Messages>
</root>
到目前为止,我成功地编写了以下xslt transormation,它只替换了一个特定的节点,但替换了values.xml中的所有值
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<!--xsl:output method="xml" indent="yes"/-->
<xsl:strip-space elements="*"/>
<xsl:variable name="vReps" select="document('file:///c:/test/values.xml')"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- replace element text -->
<xsl:template match="SSTVal[text()='Version']">
<xsl:value-of select="$vReps"/>
</xsl:template>
</xsl:stylesheet>
你能帮我更改xslt以替换匹配的元素吗。提前谢谢!
编辑:应使用XSLT 1.0
将<xsl:variable name="vReps" select="document('file:///c:/test/values.xml')"/>
更改为<xsl:variable name="vReps" select="document('file:///c:/test/values.xml')//SSTVal"/>
,然后就可以更改了
<xsl:template match="SSTVal[text()='Version']">
<xsl:value-of select="$vReps"/>
</xsl:template>
至
<xsl:template match="SSTVal[. = $vReps/@name]">
<xsl:value-of select="$vReps[current() = @name]"/>
</xsl:template>
XSLT1.0中不允许只在模式中使用变量引用,因此我们需要在模板内部进行检查:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:variable name="vReps" select="document('values.xml')//SSTVal"/>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SSTVal">
<xsl:choose>
<xsl:when test="$vReps[current() = @name]">
<xsl:value-of select="$vReps[current() = @name]"/>
</xsl:when>
<xsl:otherwise>
<!-- not sure you want to raise an error with xsl:message or leave the element -->
<xsl:call-template name="identity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
在XSLT2.0中,我们可以将代码简化为
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:param name="value-uri" select="'values.xml'"/>
<xsl:variable name="value-doc" select="document($value-uri)"/>
<xsl:key name="val" match="SSTVal" use="@name"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SSTVal[key('val', ., $value-doc)]">
<xsl:value-of select="key('val', ., $value-doc)"/>
</xsl:template>
</xsl:stylesheet>