【问题标题】:Replace elements with values from another xml file用另一个 xml 文件中的值替换元素
【发布时间】:2016-08-02 17:18:57
【问题描述】:

我有以下 xml 文件:

1) 源码.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) 值.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 转换,它仅替换一个特定节点,但使用 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

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    &lt;xsl:variable name="vReps" select="document('file:///c:/test/values.xml')"/&gt;改成&lt;xsl:variable name="vReps" select="document('file:///c:/test/values.xml')//SSTVal"/&gt;然后能改就好了

      <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>
    

    在 XSLT 1.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>
    

    在 XSLT 2.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>
    

    【讨论】:

    • 谢谢!我假设它是 XSLT 2.0,不是吗?
    • 不,在 XSLT 2.0 中,我建议定义一个键并使用它,发布的代码是 XSLT 1.0。或者我想是的,现在看我不确定我是否可以在匹配模式中使用该变量,所以我必须进行测试。
    • 你太棒了,马丁!我在测试期间弄乱了xml,这就是它不起作用的原因。现在效果很好,即使使用
    • @oachkatzlschwoaf,请参阅编辑以获取经过测试的 XSLT 1.0 尝试,恐怕模式中确实不允许使用变量引用,因此您需要在模式内部进行检查或不要'不检查,如果您确定所有元素在另一个文件中都有替换匹配项。
    猜你喜欢
    • 1970-01-01
    • 2021-11-27
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多