使用XSLT转动三个XML值

时间:2014-11-22 11:00:33

标签: xml xslt pivot

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

User_Created Controlled_Drug_Name 计数

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

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>

1 个答案:

答案 0 :(得分:1)

由于您没有提供部分XML作为示例,因此它只是一个猜测。但是如果输入XML中的节点/列的名称是Count,则可以在更改时使用

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

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

更新:如评论中所述,列名称为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>

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