XSLT 2.0 中的子字符串和分组问题

发布于 2024-11-09 08:34:31 字数 1593 浏览 0 评论 0原文

我有以下 XML:

<InterSection criteria="Microsoft-ASP">value</Intersection>
<InterSection criteria="Microsoft-MVC">value</Intersection>
<InterSection criteria="HP-MVC">value</Intersection>

我需要在 HTML 页面顶部创建 TOC,因此我需要按条件分组(“-”之前的第一部分)。

这样的不同值

  1. 我需要像Microsoft
  2. HP

我的 XSLT 有以下代码

<a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>
                <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
                      <xsl:value-of select="substring-before(@Criteria, ' - ')"/> 
                      <xsl:text>
                      </xsl:text>
                    </xsl:for-each-group>        

  </a>

但不知何故我得到了

  1. Microsoft
  2. Microsoft
  3. HP

而不是 1.微软 2. HP

我在 XSLT 中写了以下内容

  <xsl:template match="InterSection" mode="TOC">

<li>
  <a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>

    <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
        <xsl:value-of select="current-grouping-key()"/>
        <xsl:for-each select="current-group()"/>
     </xsl:for-each-group>
  </a>
</li>

I have the following XML:

<InterSection criteria="Microsoft-ASP">value</Intersection>
<InterSection criteria="Microsoft-MVC">value</Intersection>
<InterSection criteria="HP-MVC">value</Intersection>

I need to create TOC at top of my HTML page and so I need to group by criteria (First part before '-').

I need distinct values like

  1. Microsoft
  2. HP

My XSLT have following code

<a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>
                <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
                      <xsl:value-of select="substring-before(@Criteria, ' - ')"/> 
                      <xsl:text>
                      </xsl:text>
                    </xsl:for-each-group>        

  </a>

But somehow i am getting

  1. Microsoft
  2. Microsoft
  3. HP

instead of
1. Microsoft
2. HP

I have following written in my XSLT

  <xsl:template match="InterSection" mode="TOC">

<li>
  <a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>

    <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
        <xsl:value-of select="current-grouping-key()"/>
        <xsl:for-each select="current-group()"/>
     </xsl:for-each-group>
  </a>
</li>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰つ倒转 2024-11-16 08:34:31

我最后要总结一下我将在您的工作中解决的问题,以便使其正常工作(删除了以前的编辑):

  • 您的输入 xml 元素在您的转换中的大小写不正确,
  • 您引用了属性 criteria使用错误的大小写,
  • 您的 substring 表达式在第二个参数 - 周围包含太多空格,
  • 您应该使用 current-grouping-key() 来获取当前匹配组的值,
  • 模板必须与 InterSection 的父级(Root)匹配,然后您必须像您一样迭代 InterSection可以使用xsl:for-each

I'm finally going to summarize the problems I would fix in your work in order to make it work (deleted previous edits):

  • your input xml elements are not in correct case
  • in your transform you refer to the attribute criteriausing the wrong case
  • your substring expression contains too much spaces around the second argument -
  • you should use current-grouping-key() to get the value of the current matching group
  • the template must match the parent of InterSection (Root) and then you have to iterate on InterSection like you would do with xsl:for-each
憧憬巴黎街头的黎明 2024-11-16 08:34:31
           <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">

这毫无意义。 select 属性中的表达式选择单个项目。当选择了多个项目并且我们希望使用特定标准对它们进行分组时,分组就有意义。

当单个项目被“分组”时,“结果”始终是同一个项目——这正是您得到的结果。

解决办法:正确选择一组要分组的项目。或者,使用此替代解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vallKeys" select=
  "distinct-values
      (/*/*/@criteria
            /substring-before(.,'-')
      )
  "/>
 <xsl:template match="/">
  <xsl:for-each select="$vallKeys">
   <xsl:value-of select=
     "concat(position(),'.',.,'
')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当将此转换应用于以下 XML 文档时(通过更正其严重格式错误而从提供的片段派生):

<someParent>
    <InterSection criteria="Microsoft-ASP">value</InterSection>
    <InterSection criteria="Microsoft-MVC">value</InterSection>
    <InterSection criteria="HP-MVC">value</InterSection>
</someParent>

生成所需的正确结果 >:

1.Microsoft
2.HP
           <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">

This is meaningless. The expression in the select attribute selects a single item. Grouping has meaning when there are more than one items selected and we want to group them using certain criteria.

When a single item is "grouped" the "result" is always that same item -- this is exactly what you get.

Solution: Select correctly a group of items to be grouped. Or, use this alternative solution:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vallKeys" select=
  "distinct-values
      (/*/*/@criteria
            /substring-before(.,'-')
      )
  "/>
 <xsl:template match="/">
  <xsl:for-each select="$vallKeys">
   <xsl:value-of select=
     "concat(position(),'.',.,'
')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document (derived from the provided fragment by corrected its severe malformedness):

<someParent>
    <InterSection criteria="Microsoft-ASP">value</InterSection>
    <InterSection criteria="Microsoft-MVC">value</InterSection>
    <InterSection criteria="HP-MVC">value</InterSection>
</someParent>

the wanted, correct result is produced:

1.Microsoft
2.HP
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文