可以在一组字符串标记上创建XSLT密钥吗?

时间:2013-07-20 20:23:54

标签: php key xslt-1.0

我有一个包含一组文件名的字符串,例如;

"foo.jpg,bar.jpg"

我将传递给XSL样式表;

<xsl:param name="images"/>

我可以以某种方式在这些文件名上创建XSLT密钥吗?

我试过这个;

<xsl:variable name="tokens" select="str:tokenize($images, ',')"/>
<xsl:key name="mykey" match="$tokens/*" use="token"/>

但是我收到了错误;

Warning: XSLTProcessor::importStylesheet(): compilation error: file
file:///C:/root/sites/bec/ line 105 element key
in C:\root\php\lib-2013-04-23.php on line 157
Warning: XSLTProcessor::importStylesheet(): xsl:key : XPath pattern
compilation failed '//$tokens/*'

我正在使用XSLT 1.0提供PHP的libxml(版本2.7.3)。

1 个答案:

答案 0 :(得分:4)

  1. 您正在使用带有EXSLT(http://www.exslt.org/)的XSLT1.0,它在样式表中定义为xmlns:str="http://exslt.org/strings"<xsl:variable name="tokens" select="str:tokenize($images, ',')" />行声明了一个包含<token>foo.jpg</token><token>bar.jpg</token>字符串的变量。现在,您可以使用此变量来选择或比较源XML标记值/属性。

  2. 你误解了<xsl:key>元素的含义。它声明了一个可以与key()函数一起使用的命名键。当您使用像<xsl:for-each select="key('name', 'value')" />这样的函数时,它会遍历您的源XML节点,它由match元素的<xsl:key>属性声明,并搜索该值在指定的use属性中。 它不能用于搜索XSL变量,它完全没用。

  3. 看一下这个例子:

    的test.xml

    <root>
      <img src="foo.jpg" width="128" height="128" alt="First ldpi image" />
      <img src="my.jpg" width="64" height="64" alt="My image" />
      <img src="foo.jpg" width="256" height="256" alt="First hdpi image" />
      <img src="your.jpg" width="64" height="64" alt="Your image" />
      <img src="bar.jpg" width="128" height="128" alt="Second image" />
    </root>
    

    test.xsl

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:exsl="http://exslt.org/common"
       xmlns:str="http://exslt.org/strings"
        version="1.0">
    
      <xsl:param name="images" />
      <xsl:variable name="tokens" select="str:tokenize($images, ',')"/>
    
      <xsl:key name="mykey" match="img" use="@src"/>
    
      <xsl:template match="/">
        <root>
          <by-key>
            <xsl:copy-of select="key('mykey', 'my.jpg')" />
          </by-key>
          <by-node-set>
            <xsl:apply-templates />
          </by-node-set>
        </root>
      </xsl:template>
    
      <xsl:template match="/root/img[@src]">
        <xsl:if test="exsl:node-set($tokens)/text() = @src">
          <xsl:copy-of select="."/>
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>
    

    test.php的:

    <?php
    
    $xml = new DOMDocument('1.0', 'UTF-8');
    $result = $xml->load('test.xml');
    
    $xsl = new DOMDocument('1.0', 'UTF-8');
    $result = $xsl->load("test.xsl");
    
    $xslt = new XSLTProcessor();
    $xslt->setParameter('', 'images', 'foo.jpg,bar.jpg');
    $xslt->importStylesheet($xsl);
    file_put_contents('result.xml', $xslt->transformToXML($xml));
    
    ?>
    

    为result.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns:exsl="http://exslt.org/common" xmlns:str="http://exslt.org/strings">
      <by-key>
        <img src="my.jpg" width="64" height="64" alt="My image"/>
      </by-key>
      <by-node-set>
        <img src="foo.jpg" width="128" height="128" alt="First ldpi image"/>
        <img src="foo.jpg" width="256" height="256" alt="First hdpi image"/>
        <img src="bar.jpg" width="128" height="128" alt="Second image"/>
      </by-node-set>
    </root>