XSLT:如何使用变量作为查找来更新节点



这是我的source.xml:

<entries>
    <entry path="/folder/abc.txt">
        <a>abc</a>
        <b>baz</b>
    </entry>
    <entry path="/other/def.txt">
        <a>foo</a>
        <b>bar</b>
    </entry>    
</entries>

我的XSLT看起来像:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
    <xsl:variable name="lookup">
        <pair>
            <key>/folder/abc.txt</key>
            <value>/other/folder/abc.txt</value>
        </pair>
        <pair>
            <key>/other/def.txt</key>
            <value>/other/folder/misc/def.txt</value>
        </pair>
    </xsl:variable>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

因此,我可以重现我的源xml。我想要的是使用变量lookup更新path(其中path应该与key匹配以返回value)。

最终输出为:

<entries>
    <entry path="/other/folder/abc.txt">
        <a>abc</a>
        <b>baz</b>
    </entry>
    <entry path="/other/folder/misc/def.txt">
        <a>foo</a>
        <b>bar</b>
    </entry>    
</entries>

最新的要求是保持压痕的原样

我怎样才能做到这一点?

提前谢谢。

下面的XSL模板应该做到这一点。它使用EXSLT扩展函数将变量转换为节点集。(警告:如果变量中没有与路径匹配的路径,则该路径将被删除!)

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exslt="http://exslt.org/common">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:variable name="lookup">
    <pair>
      <key>/folder/abc.txt</key>
      <value>/other/folder/abc.txt</value>
    </pair>
    <pair>
      <key>/other/def.txt</key>
      <value>/other/folder/misc/def.txt</value>
    </pair>
  </xsl:variable>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="entry">
    <xsl:copy>
      <xsl:attribute name="path">
        <xsl:call-template name="replace">
          <xsl:with-param name="input" select="@path"/>
        </xsl:call-template>
      </xsl:attribute>
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>
  <!-- This template looks through each pair in lookup, finds the one whose
       key matches the input and returns the corresponding value. If none
       match, nothing will be returned. -->    
  <xsl:template name="replace">
    <xsl:param name="input"/>
    <xsl:for-each select="exslt:node-set($lookup)/pair">
        <xsl:if test="key = $input">
          <xsl:value-of select="value"/>
        </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

你可以看到它在这里工作。

您可以将查找放在一个单独的文件中,并通过litte重排使其更容易:

lookup.xml:

<entries>
    <entry path="/folder/abc.txt">/other/folder/abc.txt</entry>
    <entry path="/other/def.txt">/other/folder/misc/def.txt</entry>
</entries>

您的xslt:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="entry/@path">
        <xsl:variable name="oldpath" select="." />
        <xsl:attribute name="path"><xsl:value-of
            select="document('lookup.xml')/entries/entry[@path = $oldpath]" /></xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

请注意,如果没有匹配项,则解决方案将不会保留原始值。

相关内容

  • 没有找到相关文章

最新更新