XSL Transform与三个源文档一起创建报告

时间:2018-12-06 18:54:09

标签: xslt xslt-1.0

我在创建xsl转换时遇到困难。我的三个原始文档类似于:

<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”属性对工作组文档中项目的计数-这不会给我带来任何麻烦。

第一列显然是中心。

第二列是每个中心的唯一成员计数(由“工作人员”项目中的属性“ StaffCenter”指示),不包括在“成员资格”项目(StaffID)中没有相应条目的任何工作人员项目。这意味着对于此列,将忽略WorkgroupCenter属性。

我仅限使用XSLT 1.0。

已编辑以添加到目前为止我尝试过的内容。我一直坚持尝试汇总代码中的注释所指出的计数。我应该注意该环境是SharePoint 2010数据表单Web部件。我的示例得到了简化,因此我编辑了现有代码以使其匹配:

<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>

此外,成员资格文件是必需的,因为如果其中不存在工作人员,则不应计入他们。

1 个答案:

答案 0 :(得分:1)

为了向前发展,请考虑以下样式表:

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结果并复制了相关节点,而不仅仅是计数,以便我们可以准确地看到每个步骤的作用。应用于示例输入,结果将是:

<?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。因此,要么我将错误的节点分组,要么您的预期计数不正确。如果是前者,请编辑您的问题,并详细说明需要应用的逻辑(一个人将如何手动达到预期结果)。


已添加:

  

第二列是每个中心的唯一成员数   (由“工作人员”项目中的属性“ StaffCenter”指示)除外   在工作表中没有相应条目的任何员工项目   “会员”项目(StaffID)。

好的,这应该相对容易:

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>