XSLT:迭代xsl:key map的所有值

时间:2016-08-31 10:07:46

标签: xslt

XML

<books>
  <book title="XML Today" author="David Perry" release="2016"/>
  <book title="XML and Microsoft" author="David Perry" release="2015"/>
  <book title="XML Productivity" author="Jim Kim" release="2015"/>
</books>

以下XSL代码通过 David Perry 遍历所有书籍。

XSL

<xsl:key name="title-search" match="book" use="@author"/>

<xsl:template match="/">
   <HTML>
      <BODY>
        <xsl:for-each select="key('title-search', 'David Perry')">
         <DIV>
         <xsl:value-of select="@title"/>
         </DIV>
      </xsl:for-each>
      </BODY>
   </HTML>
</xsl:template>

HTML输出

<HTML>
  <BODY>
    <DIV>XML Today</DIV>
    <DIV>XML and Microsoft</DIV>
  </BODY>
</HTML>

现在,我不仅要通过 David Perry 的所有书籍,而是通过任何作者的所有书籍进行迭代。 相应的外环怎么样? 或者换句话说:如何遍历 title-search 键的所有值。

输出应该是这样的:

<HTML>
  <BODY>
    <H1>David Perry</H1>
    <DIV>XML Today</DIV>
    <DIV>XML and Microsoft</DIV>
    <H1>Jim Kim</H1>
    <DIV>XML Productivity</DIV>
  </BODY>
</HTML>

2 个答案:

答案 0 :(得分:2)

这应该做的工作:

<?php
    $url = "https://api.pipedrive.com/v1/deals?api_token=3bd884bb0078f836a56f1464097fb71eac9d50ce";
    $response = file_get_contents($url);
    $object = json_decode($response, true);
    foreach ($object['data'] as $key => $value) 
    {
        echo "<input type='button' value='".$value['title']."'>"; 
    }
?>

它使用了一种名为Muenchian分组的技术。 XML文档中的每个元素都隐式地具有由XSLT处理器分配给它的唯一ID(它也可以在文档本身中显式地分配id属性)。这部分:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:key name="title-search" match="book" use="@author"/>

    <xsl:template match="/books">
        <HTML>
            <BODY>
                <xsl:apply-templates select="book" />
            </BODY>
        </HTML>
    </xsl:template>

    <xsl:template match="book">
        <xsl:variable name="author" select="@author" />
        <xsl:if test="generate-id(.) = generate-id(key('title-search', $author)[1])">
            <H1><xsl:value-of select="@author" /></H1>
            <xsl:apply-templates select="//book[@author = $author]" mode="titles"/>
        </xsl:if>
    </xsl:template>

    <xsl:template match="book" mode="titles">
        <DIV>
            <xsl:value-of select="@title"/>
        </DIV>
    </xsl:template>

</xsl:stylesheet>

基本上测试当前book元素的ID是否与具有相同作者的第一个book元素的ID相同。变量generate-id(.) = generate-id(key('title-search', $author)[1]) 取自当前的书,该密钥用于查找同一作者的$author元素,<book>谓词取第一个。[1]谓词。因此,<H1>仅为该特定作者的第一次出现生成,并且在同一个if元素中,我们然后应用该模板列出该作者的书籍。该模式用于避免这些模板之间的冲突。毫无疑问,一种不使用模式的解决方案,但这也有效。您也可以使用<xsl:for-each>执行大量此操作,但我制作了单独的模板,因为XSLT是声明性的,并且在处理它时效果最佳。

在XSLT 2中进行分组要容易得多,但是当使用XSLT 1时,Muenchian分组技术通常会在您完成后提供解决方案。

答案 1 :(得分:1)

试试这个:

<强> XSLT2:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
 <HTML>
    <BODY>
        <xsl:for-each-group select="books/book" group-by="@author">
            <H1><xsl:value-of select="current-grouping-key()"/></H1>
             <xsl:for-each select="current-group()">
               <DIV><xsl:value-of select="@title"/></DIV>
             </xsl:for-each>
        </xsl:for-each-group>
    </BODY>
    </HTML>
</xsl:template>

</xsl:stylesheet>