【问题标题】:XPath/XSLT 1.0: Identifying element based on a sub element valueXPath/XSLT 1.0:根据子元素值识别元素
【发布时间】:2014-11-06 15:23:11
【问题描述】:

我正在开发一个只能将 xslt 1.0 与 XPath 1.0 一起使用的 XSLT 翻译。 假设我有以下 xml,并且我想选择 original_file_name 属性以“.prt”结尾的对象。我该怎么做?

<object>
    <object>
        <attribute name="original_file_name">file1.qaf</attribute>
        <attribute name="otherAttribute1">val</attribute>
        <attribute name="otherAttribute2">val</attribute>
    </object>
    <object>
        <attribute name="original_file_name">file2.tso</attribute>
        <attribute name="otherAttribute1">Second guess</attribute>
        <attribute name="otherAttribute2">val</attribute>
    </object>
    <object>
        <attribute name="original_file_name">file3.prt</attribute>
        <attribute name="otherAttribute1">First guess!</attribute>
        <attribute name="otherAttribute2">val</attribute>
    </object>
</object>

对于 XSLT 2.0,我找到了一个解决方案,但我无法摆脱 XPath 1.0 中不支持的 index-of。您有任何解决方法的提示吗?

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/>
    <xsl:template match="/object">
        <xsl:variable name="fileIndex">
            <xsl:call-template name="identifyFile">
                <xsl:with-param name="fileNames" select="object/attribute[@name='original_file_name']"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="fileObj" select="object[position()=$fileIndex]"/>

        <!-- do sth. with fileObj -->
        <xsl:copy-of select="$fileObj" />
    </xsl:template>
    <xsl:template name="identifyFile">
        <xsl:param name="fileNames"/>
        <xsl:choose>
            <!-- add other file extensions here -->
            <xsl:when test="$fileNames['.prt'=substring(., string-length() - 3)]">
                <xsl:value-of select="index-of($fileNames, $fileNames['.prt'=substring(., string-length() - 3)])" />
            </xsl:when>
            <xsl:when test="$fileNames['.tso'=substring(., string-length() - 3)]">
                <xsl:value-of select="index-of($fileNames, $fileNames['.tso'=substring(., string-length() - 3)])" />
            </xsl:when>
            <!-- if no known file extension has been found, just take the default one. -->
            <xsl:otherwise>
                <xsl:value-of select="1"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

编辑:在第一步中过于简化了问题:)。我添加了第二个文件扩展名,如果找不到第一个文件扩展名,应该搜索它。因此,如果示例中没有“.prt”文件,则应采用“.tso”文件。

【问题讨论】:

    标签: xslt xpath


    【解决方案1】:

    如果您只是想根据条件进行选择,那么 XPath 表达式

    object[attribute[@name='original_file_name' and substring(., string-length() - 3) = '.prt']]
    

    在您的copy-of 中就足够了。有了你编辑的样本,我想你只是想要

       <xsl:template match="/object">
         <xsl:variable name="fileNames" select="object/attribute[@name='original_file_name']"/>
            <xsl:choose>
                <!-- add other file extensions here -->
                <xsl:when test="$fileNames['.prt'=substring(., string-length() - 3)]">
                    <xsl:copy-of select="$fileNames['.prt'=substring(., string-length() - 3)]" />
                </xsl:when>
                <xsl:when test="$fileNames['.tso'=substring(., string-length() - 3)]">
                    <xsl:copy-of select="$fileNames['.tso'=substring(., string-length() - 3)]" />
                </xsl:when>
                <!-- if no known file extension has been found, just take the default one. -->
                <xsl:otherwise>
                    <xsl:copy-of select="$fileNames[1]"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
    

    【讨论】:

    • 感谢您的建议!这会很简单。我可能过于简化了我最初的问题。但我一直在想,是否也有这样一条线来解决我的真正问题。还有什么想法吗?
    • 您似乎知道如何选择您想要的元素,而不是简单地这样做,您首先计算一个索引,然后根据索引返回它以进行选择。在这种情况下,您只需一步选择并返回。我会编辑。
    • 我昨天想出了一个这样的解决方案! :) 谢谢你的帮助!
    猜你喜欢
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多