xslt 多次重用密钥

xslt reuse key multiple times

上下文:开始学习 xslt,在 grouping/keys

上遇到问题

所以,我有这个输入 XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="getInfoMinimal.xml" type="text/xsl" ?>
<domaines>
    <domaine Name="someDomain">
        <application name="someApplication1">
            <module id="0001">
                <env-entry>ejb/test</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0002">
                <env-entry>ejb/notherTest</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0003">
                <env-entry>ejb/notherTest2</env-entry>
                <requirement>Datasource1</requirement>
            </module>
            <module id="0004">
                <env-entry>ejb/notherTest3</env-entry>
                <requirement>Datasource1</requirement>
            </module>
        </application>
        <application name="someApplication2">
            <module id="0001">
                <env-entry>ejb/test</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0002">
                <env-entry>ejb/notherTest</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0003">
                <env-entry>ejb/notherTest2</env-entry>
                <requirement>Datasource1</requirement>
            </module>
            <module id="0004">
                <env-entry>ejb/notherTest3</env-entry>
                <requirement>Datasource1</requirement>
            </module>
            <module id="0001">
                <env-entry>ejb/test</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0002">
                <env-entry>ejb/notherTest</env-entry>
                <requirement>Queue1</requirement>
            </module>
            <module id="0003">
                <env-entry>ejb/notherTest2</env-entry>
                <requirement>Datasource1</requirement>
            </module>
            <module id="0004">
                <env-entry>ejb/notherTest3</env-entry>
                <requirement>Datasource3</requirement>
            </module>
        </application>
    </domaine>
</domaines>

和这个 xlst 文件(getInfoMinimal.xml):

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

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:key name="modules-by-requirement" match="module" use="requirement" />

    <xsl:template match="/">
        <html>
            <head>
                <title><xsl:value-of select="/domaines/domaine/@Name"/></title>
            </head>
            <body>
                <xsl:for-each select="/domaines/domaine/application">
                    <h1><xsl:value-of select="./@name"/></h1>
                    <xsl:for-each select="module[count(. | key('modules-by-requirement', requirement)[1]) = 1]">
                        <!--<xsl:sort select="requirement" />-->
                        <xsl:value-of select="requirement" /><br />
                        <xsl:for-each select="key('modules-by-requirement', requirement)">
                        <!--<xsl:sort select="env-entry" />
                        <xsl:value-of select="env-entry" /> (<xsl:value-of select="blabla" />)<br />-->
                        </xsl:for-each>
                    </xsl:for-each>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

我正在尝试将其呈现到 html 页面,该页面列出了每个应用程序其模块具有的所有要求。

输入隐含的规则 XML:

当前结果:

一些应用程序 1

一些应用程序2

想要的结果:

一些应用程序 1

一些应用程序2

如您所见,Queue1 和 Datasource1 不在 'someApplication2' 结果中,尽管我希望它们在。

我们将不胜感激任何帮助

由于您希望每个 application/requirement 组合都有不同的键,您可以使用应用程序名称和需求名称的串联作为键值:

<xsl:key name="modules-by-requirement" match="module" 
         use="concat(../@name, '+', requirement)" />

完整的解决方案如下所示(稍微清理一下以使用模板和更高效的 Muenchian 分组样式):

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

  <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

  <xsl:key name="modules-by-requirement" match="module" 
           use="concat(../@name, '+', requirement)" />

  <xsl:template match="/">
    <html>
      <head>
        <title>
          <xsl:value-of select="/domaines/domaine/@Name"/>
        </title>
      </head>
      <body>
        <xsl:apply-templates select="/domaines/domaine/application" />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="application">
    <xsl:variable name="appName" select="@name"/>
    <h1>
      <xsl:value-of select="$appName"/>
    </h1>
    <xsl:variable name="distinctModules"
                  select="module[generate-id() = 
                                 generate-id(key('modules-by-requirement', 
                                                 concat($appName, '+', requirement))[1])
                                ]" />
    <xsl:if test="$distinctModules">
    <ul>
      <xsl:apply-templates select="$distinctModules" />
    </ul>
    </xsl:if>
  </xsl:template>

  <xsl:template match="module">
    <li>
      <xsl:value-of select="requirement" />
    </li>
  </xsl:template>

</xsl:stylesheet>

当您的示例输入 运行 时,结果为:

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>someDomain</title>
  </head>
  <body>
    <h1>someApplication1</h1>
    <ul>
      <li>Queue1</li>
      <li>Datasource1</li>
    </ul>
    <h1>someApplication2</h1>
    <ul>
      <li>Queue1</li>
      <li>Datasource1</li>
      <li>Datasource3</li>
    </ul>
  </body>
</html>