【问题标题】:pivoting three XML values using XSLT使用 XSLT 旋转三个 XML 值
【发布时间】:2015-01-20 12:00:00
【问题描述】:

我有一个包含 3 列的 XML 文件。

用户创建 受控药物名称 数

我想使用 XSLT 对此进行 PIVOT,以便一列是行标题,一列是行,另一列是数据。

E.e.

我希望 User_Created 位于第一行,Drugs 下降,然后是数据透视表中每个的计数。

到目前为止,我有以下内容,其中包含名称和药物,但未填充计数。

任何帮助将不胜感激。

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright Strand Technology Ltd, 2008 -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:cn="http://www.strandtechnology.co.uk/carenotes" version="1.0">
  <xsl:output method="html" indent="yes" />
  <xsl:key name="UserHeader" match="QueryResults/Data/DataRow" use="User_Created" />
  <xsl:key name="DrugHeader" match="QueryResults/Data/DataRow" use="Controlled_Drug_Name" />
  <xsl:template match="QueryResults">
    <table>
      <tr style="text-align:center;">
        <td>DRUG NAME</td>
        <xsl:for-each select="Data/DataRow[count(. | key('UserHeader', User_Created)[1]) = 1]">
          <td>
            <xsl:value-of select="User_Created" />
          </td>
        </xsl:for-each>
      </tr>
      <xsl:for-each select="Data/DataRow[count(. | key('DrugHeader', Controlled_Drug_Name)[1]) = 1]">
        <tr style="text-align:center;">
          <td>
            <xsl:value-of select="Controlled_Drug_Name" />
          </td>
            <xsl:for-each select="Data/DataRow[count(. | key('UserHeader', User_Created)[1]) = 1]">
            <td>
                <xsl:value-of select="count" />
                    </td>
            </xsl:for-each>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt pivot


    【解决方案1】:

    由于您没有提供部分 XML 作为示例,这只是一个猜测。但是如果输入 XML 中的节点/列的名称是Count,如果你改变它就可以工作

    <xsl:value-of select="count" />
    

    进入

    <xsl:value-of select="Count" />
    

    更新:正如cmets中提到的,列名是count,所以这不是命名的问题。我刚刚创建了一个示例输入,不知道这是否与实际输入匹配,但使用不同的方法来获取表格。

    输入 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <QueryResults>
        <Data>
            <DataRow>
                <User_Created>user 1</User_Created>
                <Controlled_Drug_Name>name 1</Controlled_Drug_Name>
                <count>1</count>
            </DataRow>
            <DataRow>
                <User_Created>user 2</User_Created>
                <Controlled_Drug_Name>name 2</Controlled_Drug_Name>
                <count>2</count>
            </DataRow>
            <DataRow>
                <User_Created>user 3</User_Created>
                <Controlled_Drug_Name>name 3</Controlled_Drug_Name>
                <count>3</count>
            </DataRow>
            <DataRow>
                <User_Created>user 1</User_Created>
                <Controlled_Drug_Name>name 3</Controlled_Drug_Name>
                <count>4</count>
            </DataRow>
            <DataRow>
                <User_Created>user 2</User_Created>
                <Controlled_Drug_Name>name 3</Controlled_Drug_Name>
                <count>5</count>
            </DataRow>
            <DataRow>
                <User_Created>user 2</User_Created>
                <Controlled_Drug_Name>name 4</Controlled_Drug_Name>
                <count>5</count>
            </DataRow>
        </Data>
      </QueryResults>
    </root>
    

    XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output omit-xml-declaration="yes" indent="yes"/>
      <xsl:key name="kUsers" match="User_Created" use="."/>
      <xsl:key name="kRowByName" match="DataRow" use="Controlled_Drug_Name"/>
      <xsl:variable name="users" select=
          "//User_Created
          [generate-id()
          =
          generate-id(key('kUsers', .)[1])
          ]
          "/>
      <xsl:template match="QueryResults">
         <html>
            <table>
                <thead>
                    <th>Name</th>
                    <xsl:apply-templates select="$users"/>
                </thead>
                <tbody>
                    <xsl:apply-templates select=
                    "//DataRow
                    [generate-id() = 
                     generate-id(key('kRowByName', Controlled_Drug_Name))]">
                    <xsl:sort select="Controlled_Drug_Name"/>
                    </xsl:apply-templates>
                </tbody>
           </table>
        </html>
      </xsl:template>
      <xsl:template match="User_Created">
        <th>
           <xsl:value-of select="."/>
        </th>
      </xsl:template>
      <xsl:template match="DataRow">
        <tr>
           <td>
               <xsl:value-of select="Controlled_Drug_Name"/>
           </td>
           <xsl:apply-templates select="$users" mode="row">
              <xsl:with-param name="nRows"
               select="key('kRowByName', Controlled_Drug_Name)"/>
           </xsl:apply-templates>
       </tr>
      </xsl:template>
      <xsl:template match="User_Created" mode="row">
        <xsl:param name="nRows"/>
        <td>
           <xsl:value-of select=
            "$nRows[User_Created=current()]/count"/>
        </td>
      </xsl:template>
    </xsl:stylesheet>  
    

    输出:

    <html>
    <table>
      <thead>
         <th>Name</th>
         <th>user 1</th>
         <th>user 2</th>
         <th>user 3</th>
      </thead>
      <tbody>
         <tr>
            <td>name 1</td>
            <td>1</td>
            <td></td>
            <td></td>
         </tr>
         <tr>
            <td>name 2</td>
            <td></td>
            <td>2</td>
            <td></td>
         </tr>
         <tr>
            <td>name 3</td>
            <td>4</td>
            <td>5</td>
            <td>3</td>
         </tr>
         <tr>
            <td>name 4</td>
            <td></td>
            <td>5</td>
            <td></td>
         </tr>
      </tbody>
    </table>
    </html>
    

    也许您可以使用这种方法来处理实际输入。

    【讨论】:

    • 很抱歉没有这样做,数据非常敏感,所以我不想在这里添加。但是在我的示例中,计数列名称有一个小写 c。不过感谢您的评论。
    • 我觉得计数需要以某种方式组合这两个键?
    • @user3284707 是的。刚刚用一些示例输入和调整后的方法更新了我的答案。
    • 谢谢你,这正是我所追求的……天才!!
    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    相关资源
    最近更新 更多