Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
xslt顺序和分组,每个组使用_Xslt_Saxon - Fatal编程技术网

xslt顺序和分组,每个组使用

xslt顺序和分组,每个组使用,xslt,saxon,Xslt,Saxon,我试图在对每个组使用时对嵌套的分组和排序有所了解。 我的想法是首先由制作人对项目进行排序和分组。然后,当我有了这个制作人组时,我想按code对每个组进行排序。然而,目前code的顺序并不像我想的那样有效。在下面的示例中,问题在于项与code=01001-064-03有关。它应该与所有其他项目一起分组,这些项目的code以01001开头,但不是。如果我将整个项/code[text()='01001-064-03'](最后一个)移动到xml的开头,则分组工作正常 请问我的问题是什么 谢谢 <i

我试图在对每个组使用
时对嵌套的分组和排序有所了解。
我的想法是首先由
制作人对
项目进行排序和分组。然后,当我有了这个
制作人
组时,我想按
code
对每个组进行排序。然而,目前
code
的顺序并不像我想的那样有效。在下面的示例中,问题在于
code=01001-064-03
有关。它应该与所有其他
项目一起分组,这些
项目的
code
01001
开头,但不是。如果我将整个
项/code[text()='01001-064-03']
(最后一个)移动到xml的开头,则分组工作正常

请问我的问题是什么

谢谢

<items>
  <change_date>#11.11.2020 7:42:13</change_date>
  <result>
    <item>
      <code>01001-064-01</code>
      <producer>prod1</producer>
    </item>
    <item>
      <code>01001-064-02</code>
      <producer>prod1</producer>
    </item>
    <item>
      <code>def</code>
      <producer>prod1</producer>
    </item>
    <item>
      <code>ghi</code>
      <producer>prod2</producer>
    </item>
    <item>
      <code>jkl</code>
      <producer>prod3</producer>
    </item>
    <item>
      <code>abc</code>
      <producer>prod3</producer>
    </item>
    <item>
      <code>def</code>
      <producer>prod4</producer>
    </item>
    <item>
      <code>ghi</code>
      <producer>prod4</producer>
    </item>
    <item>
      <code>jkl</code>
      <producer>prod5</producer>
    </item>
    <item>
      <code>01001-064-03</code>
      <producer>prod1</producer>
    </item>
  </result>
</items>

我的想法是首先由
制作人对
项目进行排序和分组。然后,当我有了这个
制作人
组时,我想按
code
对每个组进行排序

如果这就是你想要做的,为什么还不足以做到:

XSLT 3.0

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

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="result">
    <xsl:for-each-group select="item" group-by="producer">
        <xsl:sort select="producer"/>
        <group>
            <xsl:apply-templates select="current-group()">
                <xsl:sort select="code"/>
            </xsl:apply-templates>
        </group>
    </xsl:for-each-group>
</xsl:template>
  
</xsl:stylesheet>


我正在使用XSLT2.0
saxon he 10.3


实际上,您使用的是XSLT 3.0。

也许一个组合的
分组就足够了:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="#all"  
    version="3.0">
    
  <xsl:mode on-no-match="shallow-skip"/>
  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="change_date"/>
  
  <xsl:template match="result">
    <data>
      <xsl:for-each-group select="item" composite="yes" group-by="producer, code => replace('[^a-z0-9].*$', '', 'i')">
        <xsl:sort select="producer"/>
        <xsl:sort select="code"/>
          <group>
            <xsl:apply-templates select="current-group()" />
          </group>
      </xsl:for-each-group>
    </data>
  </xsl:template>
  
  <xsl:template match="item">
    <xsl:copy-of select="."/>
  </xsl:template>
  
</xsl:stylesheet>


这就是Saxon 9.8和更高版本(例如Saxon 10)支持的XSLT 3,如果您真的需要使用XSLT 2.0处理器,那么每个group group by的嵌套
或串联分组键可以实现与上述XSLT 3中的
复合
分组键相同的效果。

因为有
生产者的后处理。基本上,一个生产商可以有多个组。分组基于功能
mf:相同产品
,因此,如果一个项目的
code
与另一个项目的
code
匹配,则应该有一个新组。是的,我使用的xslt版本是错误的。请编辑您的问题,并(1)用文字解释您要应用的逻辑和(2)添加预期结果。希望修改后的结果现在能更好地描述给我看,每个组第二个
中的排序或分组似乎不能正常工作。您给我们的是一个示例,而不是一个规则。对于每个组的两个
嵌套
,内部尝试传入前面的
同级::item
不一定会选择外部分组的
current-group()
中的项,因为同级基于XML输入的文档顺序,而不是分组填充的顺序。因此,这可能是代码没有按您的要求执行的原因。我仍然想知道你是否需要比较分组中的两个项目,你能不能推断出每个项目的
代码
的相关部分,然后在
分组中使用该部分,或者
分组相邻的项目
?你能给出一些方法吗?这个分组对我来说是新的。请记住,两个不同的生产商可以有相似的产品代码。再次感谢。我尝试了“按多个属性选择”,但我记得它不起作用,所以我从未想过该组会起作用。您提供的解决方案非常简单。仅仅是一个问题
前面的兄弟姐妹
不能像
当前-组()/前面的兄弟姐妹…
?你可以使用
当前-组()/前面的兄弟姐妹::item
或者
当前-组()/前面的兄弟姐妹::*
当然,但是兄弟姐妹轴是在节点树上定义的;根据您想要实现的目标,导航当前组中节点的同级可能有意义,但它在输入树中导航,而不是在节点序列中导航。因此,对于
当前-group()
元素,例如
a
c
元素,表达式
current-group()/前面的同级::*
将包括不属于该组的
b
元素。
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="result">
    <xsl:for-each-group select="item" group-by="producer">
        <xsl:sort select="producer"/>
        <group>
            <xsl:apply-templates select="current-group()">
                <xsl:sort select="code"/>
            </xsl:apply-templates>
        </group>
    </xsl:for-each-group>
</xsl:template>
  
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="#all"  
    version="3.0">
    
  <xsl:mode on-no-match="shallow-skip"/>
  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="change_date"/>
  
  <xsl:template match="result">
    <data>
      <xsl:for-each-group select="item" composite="yes" group-by="producer, code => replace('[^a-z0-9].*$', '', 'i')">
        <xsl:sort select="producer"/>
        <xsl:sort select="code"/>
          <group>
            <xsl:apply-templates select="current-group()" />
          </group>
      </xsl:for-each-group>
    </data>
  </xsl:template>
  
  <xsl:template match="item">
    <xsl:copy-of select="."/>
  </xsl:template>
  
</xsl:stylesheet>