Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
Xml 应用模板是否可以与Muenchian分组一起使用,而不是分别使用?_Xml_Xslt_Xpath_Muenchian Grouping - Fatal编程技术网

Xml 应用模板是否可以与Muenchian分组一起使用,而不是分别使用?

Xml 应用模板是否可以与Muenchian分组一起使用,而不是分别使用?,xml,xslt,xpath,muenchian-grouping,Xml,Xslt,Xpath,Muenchian Grouping,据我所知,在不必要时使用for each循环是一种糟糕的形式。有人能告诉我如何将XSL中带有分组的嵌套for循环转换为单个模板吗?当XML是分层的时,这似乎很容易,但对于平面XML,我还没有弄清楚执行此操作所需的XPATH表达式或其他语法 示例XML数据: <?xml version = "1.0"?> <?xml-stylesheet type = "text/xsl" href = "time_detail_employee_m.xsl"?> <Employ

据我所知,在不必要时使用for each循环是一种糟糕的形式。有人能告诉我如何将XSL中带有分组的嵌套for循环转换为单个模板吗?当XML是分层的时,这似乎很容易,但对于平面XML,我还没有弄清楚执行此操作所需的XPATH表达式或其他语法

示例XML数据:

<?xml version = "1.0"?> 
<?xml-stylesheet type = "text/xsl" href = "time_detail_employee_m.xsl"?> 
<Employees>
  <Employee>
    <COMPANY_ID>83207</COMPANY_ID>        
    <PRJ_PROJECT_ID>104</PRJ_PROJECT_ID>
    <PRJ_PROJECT_NAME>Portal</PRJ_PROJECT_NAME>
    <PERSON_ID>5881</PERSON_ID>
    <TM_FIRST_NAME>Dave</TM_FIRST_NAME>
    <TM_LAST_NAME>Morgan</TM_LAST_NAME>
    <SR_ID>3075</SR_ID>
    <SR_TITLE>Shoe Page</SR_TITLE>
    <TM_BEGIN_DT>2015-12-11T00:00:00</TM_BEGIN_DT>
    <TM_BEGIN_TIME>10:45:00</TM_BEGIN_TIME>
    <TM_END_TIME>16:30:00</TM_END_TIME>
    <TM_TIME_CD>REG</TM_TIME_CD>
    <TM_BILLABLE>F</TM_BILLABLE>        
    <TM_WEEK>50</TM_WEEK>
    <TM_CALCULATED_TIME>5.750000</TM_CALCULATED_TIME>        
  </Employee>
  <Employee>
    ...
  </Employee>
  ...
</Employees>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="group-by-person" match="Employee" use="PERSON_ID" />    
   <xsl:key name="group-by-week" match="Employee" use="concat(PERSON_ID,'|',TM_WEEK)" /> 
   <xsl:key name="group-by-day" match="Employee" use="concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT)" /> 

   <xsl:variable name="space"><xsl:text> </xsl:text></xsl:variable>

   <xsl:template match="/">
      <html><body>   
         <xsl:apply-templates />
      </body></html>
   </xsl:template>

   <xsl:template match="Employees">
      <xsl:for-each select="Employee[count(. | key('group-by-person', PERSON_ID)[1]) = 1]">
         <xsl:sort select="TM_LAST_NAME" />
         <p><xsl:value-of select="TM_FIRST_NAME" /><xsl:value-of select="$space"/><xsl:value-of select="TM_LAST_NAME" /></p><br />

               <!-- begin week grouping -->         
               <xsl:for-each select="key('group-by-person', PERSON_ID)[count(. | key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))[1]) = 1]">
                  <xsl:sort select="TM_WEEK" data-type="number"/>
                  <p><xsl:value-of select="TM_WEEK" /></p><br/>

                      <!-- begin day grouping -->
                      <xsl:for-each select="key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))[count(. | key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))[1]) = 1]">
                          <xsl:sort select="TM_BEGIN_DT" />
                          <xsl:value-of select="substring-before(TM_BEGIN_DT,'T')" />
                          <br/>
                          <xsl:for-each select="key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))">
                              <p><xsl:value-of select="TM_BEGIN_TIME" /><xsl:value-of select="$space"/><xsl:value-of select="TM_END_TIME" /></p><br/>
                          </xsl:for-each>
                          <br/><xsl:text>daily sum = </xsl:text>
                          <xsl:value-of select="sum(key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))/TM_CALCULATED_TIME)" />
                          <br/>
                      </xsl:for-each>
                   <!-- end day grouping -->
                   <br/><xsl:text>weekly sum = </xsl:text>
                   <xsl:value-of select="sum(key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))/TM_CALCULATED_TIME)" />
                   <br/>
               </xsl:for-each>               
               <!-- end week grouping -->
          <br/><xsl:text>person_id sum = </xsl:text>
          <xsl:value-of select="sum(key('group-by-person', PERSON_ID)/TM_CALCULATED_TIME)" />
          <br/>  
      </xsl:for-each>
   </xsl:template>   
</xsl:stylesheet>
Name 1 (based on PERSON_ID)
    Week 1 (based on TM_WEEK)
        Monday (based on TM_BEGIN_DT)
            time1 - time2 (TM_BEGIN_TIME - TM_END_TIME)
            time3 - time4
        Tuesday
            time1 - time2
    Week 2
        Thursday
            time1 - time2
            time3 - time4
            time5 - time6
Name 2
    Week 1
        Wednesday
            time1 - time2
Name 3, etc.

这应该是一项直截了当的任务,因为xpath表达式将与使用
xsl:for each
xsl:apply-templates
相同。唯一需要考虑的是,至少在你的例子中,你可能会得到与相同元素匹配的多个模板(在本例中<代码>雇员< /代码>)。但是,您可以通过使用
模式
属性来解决此问题

考虑一下这个
xsl:for each

  <xsl:for-each select="Employee[count(. | key('group-by-person', PERSON_ID)[1]) = 1]">
     <xsl:sort select="TM_LAST_NAME" />
     <!-- Inner code -->
  </xsl:for-each>
然后,将内部代码从for each移动到模板匹配中

<xsl:template match="Employee" mode="person">
    <!-- Inner code -->
</xsl:template>

在许多情况下,使用
xsl:for-each
实际上不应被视为“坏形式”。要记住的是,
xsl:for-each
是一个映射构造,而不是一个循环。(XSLT处理器可以自由地并行处理所选节点)。在您的例子中,对每个使用
xsl:for-each会导致过度嵌套,这会使代码更难阅读,但除此之外,它并没有什么真正的问题。

您可以发布所需输出的示例吗?如果你展示了你的目标,那么帮助就会容易得多。输出应该反映在关键声明中定义的分组。也就是说,对于每个人的ID,将列出他们相关的TM_周和每周内的TM_开始DTs。我想重申这个请求。在输出中看到您需要什么比从代码中找出它更容易。正如写作老师经常对我说的那样,“展示,不要告诉。”:)此外,对于给定的
,你的示例输入只包括一个
,还有一个
,因此对它们进行排序不会起任何作用。您的示例输入是否具有代表性?阅读您的XSL,我越来越感觉到您的输入不具有代表性——您似乎正在按其子元素对多个
元素进行分组,这表明可以有多个
元素具有相同的
值。这是正确的吗?如果是这样的话,除了提供示例输出外,如果您可以更新示例输入以显示这一点,这将非常有用。但假设有多个类似于图中所示的员工节点。是的,XSL当前会找到所有匹配的s,然后是s,然后是s,以及当天的开始和结束时间。我很好奇,这些相同的操作是否可以通过模板而不是每个STMT的嵌套来完成。将使用示例输出进行更新。谢谢,@Tim C。这正是我想要的。
<xsl:template match="Employee" mode="person">
    <!-- Inner code -->
</xsl:template>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="group-by-person" match="Employee" use="PERSON_ID" />    
   <xsl:key name="group-by-week" match="Employee" use="concat(PERSON_ID,'|',TM_WEEK)" /> 
   <xsl:key name="group-by-day" match="Employee" use="concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT)" /> 

   <xsl:output method="html" indent="yes" />

   <xsl:variable name="space"><xsl:text> </xsl:text></xsl:variable>

   <xsl:template match="/">
      <html><body>   
         <xsl:apply-templates />
      </body></html>
   </xsl:template>

   <xsl:template match="Employees">
      <xsl:apply-templates select="Employee[count(. | key('group-by-person', PERSON_ID)[1]) = 1]" mode="person">
         <xsl:sort select="TM_LAST_NAME" />
      </xsl:apply-templates>
   </xsl:template>   

   <xsl:template match="Employee" mode="person">
     <p><xsl:value-of select="TM_FIRST_NAME" /><xsl:value-of select="$space"/><xsl:value-of select="TM_LAST_NAME" /></p><br />
       <!-- begin week grouping -->         
       <xsl:apply-templates select="key('group-by-person', PERSON_ID)[count(. | key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))[1]) = 1]" mode="week">
          <xsl:sort select="TM_WEEK" data-type="number"/>
       </xsl:apply-templates>               
       <!-- end week grouping -->
        <br/><xsl:text>person_id sum = </xsl:text>
      <xsl:value-of select="sum(key('group-by-person', PERSON_ID)/TM_CALCULATED_TIME)" />
      <br/>  
   </xsl:template>

   <xsl:template match="Employee" mode="week">
      <p><xsl:value-of select="TM_WEEK" /></p><br/>
      <!-- begin day grouping -->
      <xsl:apply-templates select="key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))[count(. | key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))[1]) = 1]" mode="day">
          <xsl:sort select="TM_BEGIN_DT" />
      </xsl:apply-templates>
       <!-- end day grouping -->
       <br/><xsl:text>weekly sum = </xsl:text>
       <xsl:value-of select="sum(key('group-by-week', concat(PERSON_ID,'|',TM_WEEK))/TM_CALCULATED_TIME)" />
       <br/>
   </xsl:template>

   <xsl:template match="Employee" mode="day">
      <xsl:value-of select="substring-before(TM_BEGIN_DT,'T')" />
      <br/>
      <xsl:for-each select="key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))">
          <p><xsl:value-of select="TM_BEGIN_TIME" /><xsl:value-of select="$space"/><xsl:value-of select="TM_END_TIME" /></p><br/>
      </xsl:for-each>
      <br/><xsl:text>daily sum = </xsl:text>
      <xsl:value-of select="sum(key('group-by-day', concat(PERSON_ID,'|',TM_WEEK,'|',TM_BEGIN_DT))/TM_CALCULATED_TIME)" />
      <br/>
   </xsl:template>
</xsl:stylesheet>