【问题标题】:xslt xpath muenchian groupingxslt xpath muenchian 分组
【发布时间】:2014-03-18 09:08:20
【问题描述】:

我有以下 xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
    <rss>
     <channel>
      <item>
       <status>Identify</status>
       <component>Department A</component>
       <component>Department ABC</component>
      </item>
      <item>
       <status>Identify</status>
       <component>Department B</component>
       <component>Department BCD</component>
      </item>
      <item>
       <status>In Progress</status>
       <component>Department A</component>
       <component>Redundant</component>
      </item>
      <item>
       <status>Identify</status>
       <component>Department B</component>
       <component>Redundant</component>
      </item>
     </channel>
    </rss>

我希望 html 中的输出如下表所示

Departments       | Identify | In Progress
Department A      |    0     |    1
Department B      |    1     |    0
Department ABC    |    1     |    0
Department BCD    |    1     |    0
Total (4 records) |    3     |    1  

这就是数字背后的逻辑。 如果一个项目有多个组件,请仅选择一个名称最长的组件。 必须忽略任何不以“部门”开头的组件。 每个项目始终只有一个状态。

我对 xslt 和 xpath 很陌生。即使经过大量的谷歌搜索,我现在已经被困在这个问题上好几天了。有哪位大师,请帮忙:) 真的很感激。

非常感谢。 比派


这是我迄今为止所尝试的……显然,离我想要的位置还有很长的路要走。但是我对接下来的步骤一无所知,因为 xslt 逻辑与普通的顺序编程逻辑有很大不同。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>
    <xsl:key name="components" match="/rss/channel/item/component" use="./text()"/>

    <xsl:template match="/rss/channel">
        <xsl:for-each select="item/component[generate-id(.) = generate-    id(key('components', .))]">
            <xsl:sort select="."/>
            <xsl:if test="contains(text(),'Department')">
            <h1>
                <xsl:value-of select="text()"/>
                <xsl:value-of select="count(key('components', .))"/>
            </h1>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 只能使用 XSLT 1.0 吗?如果您有 XSLT 2.0 处理器,则不需要 Muenchian 分组来对元素进行分组。
  • 是的,很遗憾,我只能使用 XSLT 1.0。
  • 很好。我不确定这里是否需要分组。给定部门可以有多个“确定”或“进行中”吗?
  • 是的,可以有 Mathias。

标签: xml xslt xpath xslt-1.0


【解决方案1】:

您实际上并不需要为此使用 Muenchian 分组。以下解决方案无需任何分组机制即可工作。

样式表

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>

    <xsl:template match="/rss/channel">
        <html>
            <body>
            <table border="solid">
                <tr>
                    <td>Departments</td>
                    <td>Identify</td>
                    <td>In Progress</td>
                </tr>
                <xsl:apply-templates select="//component"/>
                <tr>
                <xsl:variable name="total" select="count(//component[starts-with(.,'Department') and not(. = preceding::component/text())])"/>
                    <td>
                        <xsl:value-of select="concat('Total (',$total,' records)')"/>
                    </td>
                    <td>
                        <xsl:value-of select="count(//item[status = 'Identify'])"/>
                    </td>
                    <td>
                        <xsl:value-of select="count(//item[status = 'In Progress'])"/>
                    </td>
                </tr>
            </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="component[starts-with(.,'Department') and not(. = preceding::component/text())]">
        <tr>
            <td>
                <xsl:value-of select="."/>
            </td>
            <td>
                <xsl:value-of select="count(//item[status = 'Identify' and component = current() and not(component[. != current() and string-length(.) &gt; string-length(current())])])"/>
            </td>
            <td>
                <xsl:value-of select="count(//item[status = 'In Progress' and component = current() and not(component[. != current() and string-length(.) &gt; string-length(current())])])"/>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

输出

<html>
   <body>
      <table border="solid">
         <tr>
            <td>Departments</td>
            <td>Identify</td>
            <td>In Progress</td>
         </tr>
         <tr>
            <td>Department A</td>
            <td>0</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Department ABC</td>
            <td>1</td>
            <td>0</td>
         </tr>
         <tr>
            <td>Department B</td>
            <td>1</td>
            <td>0</td>
         </tr>
         <tr>
            <td>Department BCD</td>
            <td>1</td>
            <td>0</td>
         </tr>
         <tr>
            <td>Total (4 records)</td>
            <td>3</td>
            <td>1</td>
         </tr>
      </table>
   </body>
</html>

呈现的 HTML 输出

【讨论】:

  • 虽然如果你也能把它合并起来就完美了。 “如果一个项目有多个组件,则只选择一个名称最长的组件。”
  • @user3304762 你说得对——我忽略了这一点。我已经编辑了我的答案 - 现在稍微复杂了一点。
  • 天哪!那很快!非常感谢@Mathias。现在我想知道为什么我浪费时间坐在这个上面。应该早点在这里发帖寻求大师的帮助 :-) 再次感谢。
猜你喜欢
  • 2014-03-19
  • 1970-01-01
  • 2021-11-20
  • 2018-03-28
  • 2021-11-04
  • 1970-01-01
  • 2016-05-19
  • 2019-05-20
  • 2019-12-07
相关资源
最近更新 更多