简体   繁体   English

我想更好地了解使用Muenchian分组的XSLT 1.0嵌套分组

[英]I want to better understand XSLT 1.0 nested grouping using Muenchian grouping

I have XML data and would like to group it by INSPTR and ELVINSP_DT. 我有XML数据,想按INSPTR和ELVINSP_DT进行分组。 Questions at the end of the post. 帖子末尾的问题。

Here is my XML: 这是我的XML:

<AS400_ELVPINS00Collection>
  <ObjList>
    <AS400_ELVPINS00>
      <ID>123456</ID>
      <ELVINSP_DT>2014-05-01</ELVINSP_DT>
      <DetailData>Out Sick</DetailData>
      <INSPTR>
        <ID>555123</ID>
        <INSPTR_NAME>Doe, John P</INSPTR_NAME>
        <MoreDetailData>Northeast Region</MoreDetailData>
      </INSPTR>
    </AS400_ELVPINS00>
    <AS400_ELVPINS00>
      <ID>123459</ID>
      <ELVINSP_DT>2014-05-02</ELVINSP_DT>
      <DetailData>Nobody showed up</DetailData>
      <INSPTR>
        <ID>555123</ID>
        <INSPTR_NAME>Doe, John P</INSPTR_NAME>
        <MoreDetailData>Northeast Region</MoreDetailData>
      </INSPTR>
    </AS400_ELVPINS00>
    <AS400_ELVPINS00>
      <ID>123463</ID>
      <ELVINSP_DT>2014-05-01</ELVINSP_DT>
      <DetailData>Job Location was clear</DetailData>
      <INSPTR>
        <ID>555124</ID>
        <INSPTR_NAME>Smith, John T</INSPTR_NAME>
        <MoreDetailData>South Central Region</MoreDetailData>
      </INSPTR>
    </AS400_ELVPINS00>
  </ObjList>
</AS400_ELVPINS00Collection>

I'd like the data listed like this: 我想要这样列出的数据:

Doe, John P  
 2014-05-01 - Out Sick  
 2014-05-02 - Nobody showed up  
Smith, John T  
 2014-05-01 - Job Location was clear  

Here is what I'm trying for XSLT: 这是我为XSLT尝试的方法:

  <xsl:key name="keyInsptr" match="ObjList/AS400_ELVPINS00" use="INSPTR" />
  <xsl:key name="keyDate" match="ObjList/AS400_ELVPINS00" use="ELVINSP_DT" />

    <fo:flow flow-name="xsl-region-body">
      <xsl:for-each select="ObjList/AS400_ELVPINS00[generate-id(.)=generate-id(key('keyInsptr',INSPTR)[1])]">
        <xsl:sort select="INSPTR/INSPTR_NAME"/>

        <!-- This part works --> 
        <fo:block>
          <xsl:value-of select="INSPTR/INSPTR_NAME" />
        </fo:block>

        <!-- This part DOES NOT work -->
        <xsl:variable name="vrInsptID">
          <xsl:value-of select="INSPTR/INSPTR_NAME"/>
        </xsl:variable>
        <xsl:variable name="lstInsp" select="ObjList/AS400_ELVPINS00[INSPTR/INSPTR_NAME=vrInsptrID]" />
        <xsl:for-each select="lstInsp[generate-id(.)=generate-id(key('keyDate',ELVINSP_DT)[1])]">
          <fo:block>
            <xsl:text> - </xsl:text>
            <xsl:call-template name="dateFormat">
              <xsl:with-param name="value" select="lstInsp/ELVINSP_DT" />
            </xsl:call-template>
          </fo:block>
        </xsl:for-each>


      </xsl:for-each>
    </fo:flow>

I understand that generate-id creates a unique 'id' at runtime for an element, so I am assuming that generate-id(.) will generate an id for each ObjList/AS400_ELVPINS00 element to use in the match, correct? 我知道generate-id在运行时会为元素创建一个唯一的“ id”,所以我假设generate-id(。)将为每个ObjList / AS400_ELVPINS00元素生成一个ID,用于匹配中,对吗?

What is generate-id(key('keyInsptr',INSPTR)[1]) doing? generate-id(key('keyInsptr',INSPTR)[1])在做什么? What kind of results does that make? 那会产生什么样的结果? I'm trying to visualize this. 我正在尝试将其形象化。

When I do the 'for-each' on keyInsptr, what Node-set am I working with inside that for-each? 当我在keyInsptr上执行“ for-each”操作时,我在该for-each内部使用哪个节点集?

How do I get the inner 'for-each' to cycle through the dates correctly? 如何获取内部的“ for-each”以正确循环显示日期?

I am not just looking to get this working, but to also understand how it should work. 我不仅希望使它起作用,而且还要了解它应该如何起作用。 Thank you. 谢谢。

If you are new to Muenchian grouping and don't understand the concept then I don't think it is a good idea starting a project with nested grouping and two keys. 如果您是Muenchian分组的新手,并且不了解该概念,那么我认为使用嵌套分组和两个键启动项目并不是一个好主意。 As for your problems to understand the predicate generate-id(.)=generate-id(key('keyInsptr',INSPTR)[1]) , it is just making sure the for-each processes the first item in each group based on the key value as the expression key('keyInsptr',INSPTR) finds all items of the same key value, the positional predicate key('keyInsptr',INSPTR)[1] takes the first of those items and the generate-id check is just the XSLT/XPath 1.0 way of comparing the identity of two nodes (with XPath 2.0 you could just write [. is key('keyInsptr',INSPTR)[1]] although you would use for-each-group instead). 至于您要了解谓词generate-id(.)=generate-id(key('keyInsptr',INSPTR)[1]) ,只需确保for-each根据以下内容处理每个组中的第一项键值作为表达式key('keyInsptr',INSPTR)查找相同键值的所有项,位置谓词key('keyInsptr',INSPTR)[1]取其中的第一个,generate-id检查为只是比较两个节点的身份的XSLT / XPath 1.0方法(使用XPath 2.0,您可以编写[. is key('keyInsptr',INSPTR)[1]]尽管您可以使用for-each-group代替)。 Thus the 就这样

  <xsl:for-each select="ObjList/AS400_ELVPINS00[generate-id(.)=generate-id(key('keyInsptr', INSPTR)[1])]">

processes the first AS400_ELVPINS00 (in document order) of each group having the same key value. 处理每个具有相同键值的组的第一个AS400_ELVPINS00 (按文档顺序)。

Now to extend the grouping you usually concatenate key values with a separator character not in the expected key values so with 现在,为了扩展分组,通常将键值与分隔符(不在期望的键值中)连接在一起,因此

  <xsl:key name="keyDate" match="ObjList/AS400_ELVPINS00" use="concat(INSPTR, '|', ELVINSP_DT)" />

and

    <xsl:for-each select="key('keyInsptr', INSPTR)[generate-id(.)=generate-id(key('keyDate', concat(INSPTR, '|', ELVINSP_DT))[1])]">
      <fo:block>
        <xsl:text> - </xsl:text>
        <xsl:call-template name="dateFormat">
          <xsl:with-param name="value" select="ELVINSP_DT" />
        </xsl:call-template>
      </fo:block>
    </xsl:for-each>

you would implement a second level of grouping. 您将实施第二级分组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM