0

这里有很多帮助将 XSLT 1.0 转换为 2.0,但我需要另辟蹊径!

好的,我有一个在 XSLT 2.0 中工作的 XSL 文件:我需要将此文件转换为 XSLT 1.0。现在,我知道转换已经挂在“结果文档”上,但我不知道如何解决这个问题。而且,我不确定我的其他信息是否会转换为 1.0:我的 value-of select= 语句是否仍然有效?帮助!(谢谢)!

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
    <xsl:result-document href="output.xml" method="xml">
        <playlist>
            <xsl:for-each select="//dict[preceding-sibling::*[1]='Tracks']/dict">
                <Track>
                    <Artist>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Artist']"/>
                    </Artist>
                    <Album>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Album']"/>
                    </Album>
                    <Songname>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Name']"/>
                    </Songname>
                    <TrackID>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Track ID']"/>
                    </TrackID>
                    <TagID>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Tag ID']"/>
                    </TagID>
                </Track>
            </xsl:for-each>

            <xsl:for-each select="//dict[preceding-sibling::*[1]='Upload Information']">
                <Description>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Playlist Description']"/>
                </Description>
                <Title>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Playlist Title']"/>
                </Title>
                <Username>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Username']"/>
                </Username>
                <Token>
                    <xsl:value-of select="child::*[preceding-sibling::*[1] = 'Token']"/>
                </Token>
            </xsl:for-each>
        </playlist>
    </xsl:result-document>
</xsl:template>

4

2 回答 2

1

考虑到这result-document是 XSLT 2.0 中的新功能,并且没有特定处理器扩展的 XSLT 1.0 根本不允许创建多个结果文档,因此通常无法将使用的样式表转换result-document为 XSLT 1.0。

但是,在您的代码段中,该result-document指令位于与单个文档节点匹配的模板内,/因此您可以简单地将其删除并使用

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
        <playlist>
            <xsl:for-each select="//dict[preceding-sibling::*[1]='Tracks']/dict">
                <Track>
                    <Artist>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Artist']"/>
                    </Artist>
                    <Album>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Album']"/>
                    </Album>
                    <Songname>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Name']"/>
                    </Songname>
                    <TrackID>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Track ID']"/>
                    </TrackID>
                    <TagID>
                        <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Tag ID']"/>
                    </TagID>
                </Track>
            </xsl:for-each>

            <xsl:for-each select="//dict[preceding-sibling::*[1]='Upload Information']">
                <Description>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Playlist Description']"/>
                </Description>
                <Title>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Playlist Title']"/>
                </Title>
                <Username>
                    <xsl:value-of select="*[preceding-sibling::*[1][local-name()='key'] = 'Username']"/>
                </Username>
                <Token>
                    <xsl:value-of select="child::*[preceding-sibling::*[1] = 'Token']"/>
                </Token>
            </xsl:for-each>
        </playlist>

</xsl:template>

当然,您需要确保使用正确的参数运行 XSLT 处理器,以将其结果写入output.xml.

至于value-of,请检查是否有任何使用的表达式选择了输入 XML 文档中的多个节点。但是您只需要检查样式表是否曾经有过一次version="2.0"并且是使用 XSLT 2.0 处理器以这种方式运行的。您发布的代码片段具有version="1.0",这样即使 XSLT 2.0 处理器也会以使用value-of语义(第一个选定节点的输出字符串值)的向后兼容模式运行它。

因此,如果使用 version="2.0" 它们输出多个值并且您希望使用 version="1.0" 保留它,则 value-of 只需要适应。你需要使用for-each然后例如通过替换

                    <xsl:value-of select="child::*[preceding-sibling::*[1] = 'Token']"/>

  <xsl:for-each select="child::*[preceding-sibling::*[1] = 'Token']">
    <xsl:if test="position() > 1"><xsl:text> </xsl:text></xsl:if>
    <xsl:value-of select="."/>
  </xsl:for-each>
于 2013-06-11T13:31:45.753 回答
0

使用 xslt-1.0 的代码的唯一问题是<xsl:result-document href="output.xml" method="xml">. xslt-1.0 不支持此功能

一种可能的解决方案是删除它(xsl:result-document)并将“stdout”输出重定向到文件。这取决于您使用的工具。

还有一些 xlst 处理器支持一些扩展。例如,使用 xsltproc,您可以将 xsl:result-document 替换为 xsl:document。

于 2013-06-11T13:31:15.657 回答