使用三个源文件进行 XSL 转换以创建报告 [英] XSL Transform with three source documents to create report

查看:30
本文介绍了使用三个源文件进行 XSL 转换以创建报告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在创建 xsl 转换时遇到困难.我的三个源文件类似于:

I'm having difficulty creating an xsl transformation. My three source documents are similar to:

<dsQueryResponse>
 <Workgroup>
  <Items>
   <Item WorkgroupID="4001" WorkgroupCenter="Center1"/>
   <Item WorkgroupID="4002" WorkgroupCenter="Center1"/>
   <Item WorkgroupID="4003" WorkgroupCenter="Center2"/>
  </Items>
 </Workgroup>
 <Staff>
  <Items>
   <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1" />
   <Item StaffName="Bill Smith" StaffCenter="Center1" StaffID="BS1" />
   <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1" />
   <Item StaffName="Donald Hill" StaffCenter="Center2" StaffID="DH1" />
   <Item StaffName="Evan Dolan" StaffCenter="Center3" StaffID="ED1" />
   <Item StaffName="Frank Miller" StaffCenter="Center3" StaffID="FM1" />
  </Items>
 </Staff>
 <Membership>
  <Items>
   <Item StaffID="AJ1" WorkgroupID="4001" />
   <Item StaffID="AJ1" WorkgroupID="4001" />
   <Item StaffID="AJ1" WorkgroupID="4003" />
   <Item StaffID="CG1" WorkgroupID="4001" />
   <Item StaffID="CG1" WorkgroupID="4003" />
   <Item StaffID="DH1" WorkgroupID="4002" />
   <Item StaffID="ED1" WorkgroupID="4003" />
  </Items>
 </Membership>
</dsQueryResponse>

我想要的输出是

Center   | Unique Staff | Count (Workgroups)
------------------------------
Center1  |    1         |   2
Center2  |    2         |   1
Center3  |    1         |   0

第三列只是工作组文档中WorkgroupCenter"属性的项目计数 - 这不会给我带来任何麻烦.

The third column is simply a count of items in the Workgroup document by the "WorkgroupCenter" attribute - this is not giving me any trouble.

第一列显然是中心.

第二列是每个中心的唯一成员数(由员工"项目中的员工中心"属性表示),不包括在会员"项目(员工 ID)中没有相应条目的任何员工项目.这意味着对于此列,将忽略 WorkgroupCenter 属性.

The second column is the count of unique members of each Center (indicated by attribute "StaffCenter" in the "Staff" Items) excluding any Staff Items that do not have a corresponding entry in the "Membership" Items (StaffID). This means that for this column, the WorkgroupCenter attribute is ignored.

我仅限于 XSLT 1.0.

I am limited to XSLT 1.0.

编辑以添加我迄今为止尝试过的内容.正如我在代码中的评论所指出的那样,我一直在尝试汇总计数.我应该注意到环境是一个 SharePoint 2010 数据表单 Web 部件.我的例子被简化了,所以我编辑了我现有的代码来匹配:

Edited to add what I have attempted so far. I'm stuck at trying to aggregate the counts as noted by my comment in the code. I should note the environment is a SharePoint 2010 Data Form Web Part. My example was simplified, so I've edited my existing code to match:

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
 <xsl:output method="html" indent="no"/>
 <xsl:decimal-format NaN=""/>
 <xsl:param name="dvt_apos">'</xsl:param>
 <xsl:param name="ManualRefresh"></xsl:param>
 <xsl:param name="dvt_firstrow">1</xsl:param>
 <xsl:param name="dvt_nextpagedata" />
 <xsl:variable name="dvt_1_automode">0</xsl:variable>

 <xsl:key name="staffCenter" match="/dsQueryResponse/Staff/Items/Item" use="@StaffCenter"/>
 <xsl:key name="workgroupCenter" match="/dsQueryResponse/Workgroup/Items/Item" use="@WorkgroupCenter"/>

 <xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
  <xsl:variable name="centers" select="/dsQueryResponse/Staff/Items/Item[count (. | key('staffCenter',@StaffCenter)[1]) = 1]" />
  <xsl:variable name="workgroupCenters" select="/dsQueryResponse/Workgroup/Items/Item[count (. | key('workgroupCenter',@WorkgroupCenter)[1]) = 1]" />

  <table>
   <tr>
    <th>Center</th>
    <th>Unique Representative for Activities</th>
    <th>Active Workgroups</th>
   </tr>

   <xsl:for-each select="$centers">
    <tr>
     <td>
      <xsl:value-of select="@StaffCenter" />
     </td>
     <td>
      <xsl:variable name="CurrentCenterNodes" select="key('staffCenter',@StaffCenter)" />

      <!-- This gives me count of the number of instances of a particular staff member. 
           What I want is a count of the number of staff members where their total is greater than 0 -->
      <xsl:for-each select="$CurrentCenterNodes">
       <xsl:value-of select="@StaffID"/> -
       <xsl:value-of select="count(/dsQueryResponse/Membership/Items/Item[@Title=current()/@StaffID])"/>
       <br/>
      </xsl:for-each>
     </td>
     <td>
      <xsl:variable name="WorkgroupCenterLeadNodes" select="key('workgroupCenter',@StaffCenter)" />
      <xsl:value-of select="count($WorkgroupCenterLeadNodes)" />
     </td>
    </tr>
   </xsl:for-each>
  </table>
 </xsl:template>
</xsl:stylesheet>

此外,Membership 文件是必要的,因为如果其中不存在工作人员,则不应将其计算在内.

Additionally, the Membership document is necessary because if a Staff Member does not exist in it then they should not be counted.

推荐答案

为了推动这一点,请考虑以下样式表:

In the interest of moving this forward, consider the following stylesheet:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="staff-by-center" match="Staff/Items/Item" use="@StaffCenter"/>
<xsl:key name="workgroup-by-center" match="Workgroup/Items/Item" use="@WorkgroupCenter"/>
<xsl:key name="membership-by-workgroup" match="Membership/Items/Item" use="@WorkgroupID"/>
<xsl:key name="staff-by-id" match="Staff/Items/Item" use="@StaffID"/>

<xsl:template match="/dsQueryResponse">
    <root>
        <!-- for each distinct center -->
        <xsl:for-each select="Staff/Items/Item[count(.|key('staff-by-center', @StaffCenter)[1]) = 1]">
            <xsl:variable name="center" select="@StaffCenter" />
            <!-- workgroups associated with the current center -->
            <xsl:variable name="workgroups" select="key('workgroup-by-center', $center)" />
            <!-- memberships associated with the workgroups -->
            <xsl:variable name="memberships" select="key('membership-by-workgroup', $workgroups/@WorkgroupID)" />
            <!-- distinct staff listed in memberships -->
            <xsl:variable name="staff" select="key('staff-by-id', $memberships/@StaffID)" />
            <center>
                <name>
                    <xsl:value-of select="$center" />
                </name>
                <workgroups>
                    <xsl:copy-of select="$workgroups" />
                </workgroups>
                <memberships>
                    <xsl:copy-of select="$memberships" />
                </memberships>
                <all-staff>
                    <xsl:copy-of select="$staff" />
                </all-staff>
                <center-staff>
                    <xsl:copy-of select="$staff[@StaffCenter=$center]" />
                </center-staff>
            </center>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

我使用了一个 XML 结果并复制了相关节点,而不是仅仅计算它们,以便我们可以准确地看到每个步骤的作用.应用于您的示例输入,结果将是:

I have used an XML result and copied the relevant nodes instead of just counting them, so that we can see exactly what each step does. Applied to your example input, the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <center>
    <name>Center1</name>
    <workgroups>
      <Item WorkgroupID="4001" WorkgroupCenter="Center1"/>
      <Item WorkgroupID="4002" WorkgroupCenter="Center1"/>
    </workgroups>
    <memberships>
      <Item StaffID="AJ1" WorkgroupID="4001"/>
      <Item StaffID="AJ1" WorkgroupID="4001"/>
      <Item StaffID="CG1" WorkgroupID="4001"/>
      <Item StaffID="DH1" WorkgroupID="4002"/>
    </memberships>
    <all-staff>
      <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1"/>
      <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1"/>
      <Item StaffName="Donald Hill" StaffCenter="Center2" StaffID="DH1"/>
    </all-staff>
    <center-staff>
      <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1"/>
    </center-staff>
  </center>
  <center>
    <name>Center2</name>
    <workgroups>
      <Item WorkgroupID="4003" WorkgroupCenter="Center2"/>
    </workgroups>
    <memberships>
      <Item StaffID="AJ1" WorkgroupID="4003"/>
      <Item StaffID="CG1" WorkgroupID="4003"/>
      <Item StaffID="ED1" WorkgroupID="4003"/>
    </memberships>
    <all-staff>
      <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1"/>
      <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1"/>
      <Item StaffName="Evan Dolan" StaffCenter="Center3" StaffID="ED1"/>
    </all-staff>
    <center-staff>
      <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1"/>
    </center-staff>
  </center>
  <center>
    <name>Center3</name>
    <workgroups/>
    <memberships/>
    <all-staff/>
    <center-staff/>
  </center>
</root>

现在,如您所见,这些结果与您的预期输出不匹配 - 例如,Center2 下没有任何节点组的计数为 2.所以要么我对错误的节点进行分组,要么您的预期计数已关闭.如果是前者,请编辑您的问题并详细说明需要应用的逻辑(如何手动达到预期结果).

Now, as you can see, these results do not match your expected output - for example, no group of nodes under Center2 has a count of 2. So either I am grouping the wrong nodes, or your expected counts are off. If the former, please edit your question and elaborate on the logic that needs to be applied (how would one arrive at the expected result manually).

第二列是每个中心的唯一成员数(由员工"项中的员工中心"属性表示)不包括没有相应条目的任何员工项目会员"项目(员工 ID).

The second column is the count of unique members of each Center (indicated by attribute "StaffCenter" in the "Staff" Items) excluding any Staff Items that do not have a corresponding entry in the "Membership" Items (StaffID).

好的,那么这应该相对容易:

Okay then this should be relatively easy:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="staff-by-center" match="Staff/Items/Item" use="@StaffCenter"/>
<xsl:key name="memberhip-by-staff" match="Membership/Items/Item" use="@StaffID"/>

<xsl:template match="/dsQueryResponse">
    <root>
        <!-- for each distinct center -->
        <xsl:for-each select="Staff/Items/Item[count(.|key('staff-by-center', @StaffCenter)[1]) = 1]">
            <xsl:variable name="center" select="@StaffCenter" />
            <!-- staff at current center -->
            <xsl:variable name="all-staff" select="key('staff-by-center', $center)" />
            <!-- exclude staff with no memberships -->
            <xsl:variable name="staff" select="$all-staff[key('memberhip-by-staff', @StaffID)]" />
            <center>
                <name>
                    <xsl:value-of select="$center" />
                </name>
                <all-staff>
                    <xsl:copy-of select="$all-staff" />
                </all-staff>
                <staff>
                    <xsl:copy-of select="$staff" />
                </staff>
            </center>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <center>
    <name>Center1</name>
    <all-staff>
      <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1"/>
      <Item StaffName="Bill Smith" StaffCenter="Center1" StaffID="BS1"/>
    </all-staff>
    <staff>
      <Item StaffName="Anne Jones" StaffCenter="Center1" StaffID="AJ1"/>
    </staff>
  </center>
  <center>
    <name>Center2</name>
    <all-staff>
      <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1"/>
      <Item StaffName="Donald Hill" StaffCenter="Center2" StaffID="DH1"/>
    </all-staff>
    <staff>
      <Item StaffName="Charles Glover" StaffCenter="Center2" StaffID="CG1"/>
      <Item StaffName="Donald Hill" StaffCenter="Center2" StaffID="DH1"/>
    </staff>
  </center>
  <center>
    <name>Center3</name>
    <all-staff>
      <Item StaffName="Evan Dolan" StaffCenter="Center3" StaffID="ED1"/>
      <Item StaffName="Frank Miller" StaffCenter="Center3" StaffID="FM1"/>
    </all-staff>
    <staff>
      <Item StaffName="Evan Dolan" StaffCenter="Center3" StaffID="ED1"/>
    </staff>
  </center>
</root>

这篇关于使用三个源文件进行 XSL 转换以创建报告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆