【问题标题】:XSLT: Change part of a path stringXSLT:更改路径字符串的一部分
【发布时间】:2015-07-28 19:04:07
【问题描述】:

我是 XSLT 1.0 新手。在我的 XML 中的字符串元素中,我想将 jar 文件 (C:\abc\my.jar) 路径的目录部分更改为静态字符串并保留 jar 文件名 ($PATH_VAR$\my.jar )。

原始的 XML sn-p 看起来像:

<object class="someclass">
   <property name="path">
      <string><![CDATA[C:\abc\my.jar]]></string>
   </property>
</object>

我希望转换后的 XML 是:

<object class="someclass">
   <property name="path">
      <string><![CDATA[$PATH_VAR$\my.jar]]></string>
   </property>
</object>

注意原始路径可以是任意长度(\\xyz\abc 或 Z:\abc\def\ghi),jar 文件可以任意命名。

我不确定如何解析原始路径字符串并仅更改其中的目录部分。请帮忙!

-杰夫

【问题讨论】:

  • "仅更改父路径部分" 父部分不是第一个"\"之前的部分吗?这将使您的结果"$PATH_VAR$\abc\my.jar",不是吗? --附言请注明 XSLT 1.0 或 2.0。
  • 父级我的意思是“\my.jar”。我目前正在使用 XSLT 2.0。
  • 我删除了对父路径的引用,希望能避免混淆。

标签: xslt


【解决方案1】:

仅提取文件名 - 即 last \ 分隔符之后的部分 - 在 XSLT 2.0 中很容易:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="string"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="string/text()">
    <xsl:text>$PATH_VAR$\</xsl:text>
    <xsl:value-of select="tokenize(., '\\')[last()]"/>
</xsl:template>

</xsl:stylesheet>

【讨论】:

  • 非常感谢您的快速回答!但是,我刚刚阅读了另一篇文章,发现我确实在使用 XLST 1.0。对此感到抱歉。
  • @JeffM 哪个特定的 XSLT 1.0 处理器?
  • 我的 xsl 文件中的样式表行:w3.org/1999/XSL/Transform">。是这个意思吗?
  • 不,我的意思是哪个 XSLT 引擎运行您的样式表。在这里查看如何找到:stackoverflow.com/questions/25244370/…
【解决方案2】:

这是 xslt 1.0。但看起来你正在使用 xslt 2.0 所以它没用 =)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" cdata-section-elements="string"/>

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="string/text()">
        <xsl:choose>
            <xsl:when test="substring-after(., '\')">
                <xsl:call-template name="process">
                    <xsl:with-param name="left" select="."/>
                </xsl:call-template>
            </xsl:when>
            <!-- no slash == no $PATH_VAR$ -->
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="process">
        <xsl:param name="left"/>

        <xsl:choose>
            <!-- if we have at least one slash ahead - cut everything before first slash and call template recursively -->
            <xsl:when test="substring-after($left, '\')">
                <xsl:call-template name="process">
                    <xsl:with-param name="left" select="substring-after($left, '\')"/>
                </xsl:call-template>
            </xsl:when>
            <!-- if there are no slashes ahead then we have only file name left, that's all -->
            <xsl:otherwise>
                <xsl:value-of select="concat('$PATH_VAR$\', $left)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

  • '我目前正在使用 XSLT 2.0' vs. '我刚刚阅读了另一篇文章,发现我真的在使用 XLST 1.0' - 我的脑袋现在要爆炸了 :)
猜你喜欢
  • 1970-01-01
  • 2011-07-05
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多