用另一个xml文件中的值替换元素



我有以下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>

相关内容

  • 没有找到相关文章

最新更新