XSL Transform с тремя исходными документами для создания отчета - PullRequest
0 голосов
/ 06 декабря 2018

У меня проблемы с созданием преобразования 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.Мой пример был упрощен, поэтому я отредактировал свой существующий код, чтобы он соответствовал:

<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 голосов
/ 07 декабря 2018

В целях продвижения вперед рассмотрим следующую таблицу стилей:

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" в пунктах "Staff"), исключая любые элементы Staff.которые не имеют соответствующей записи в элементах «Членство» (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>
...