简体   繁体   中英

Get XSLT to place XML data in correct columns

I was wondering if an xslt guru could me solve this problem.

I have the following XML:

<profile>
    <list xid="data.table">
        <data-detail-value>
            <name>Name</name>
            <dbid>1</dbid>
            <value>Tim</value>
        </data-detail-value>
        <data-detail-value>
            <name>Area</name>
            <dbid>3</dbid>
            <value>New York</value>
        </data-detail-value>
        <data-detail-value>
            <name>Business</name>
            <dbid>6</dbid>
            <value>Drex Technology</value>
        </data-detail-value>
        <data-detail-value>
            <name>Ethnicity</name>
            <dbid>8</dbid>
            <value>Spanish</value>
        </data-detail-value>
    </list>
    <list xid="data.table">
        <data-detail-value>
            <name>Name</name>
            <dbid>1</dbid>
            <value>Bethany</value>
        </data-detail-value>
        <data-detail-value>
            <name>Tasks</name>
            <dbid>7</dbid>
            <value>Regulation</value>
        </data-detail-value>
        <data-detail-value>
            <name>Position</name>
            <dbid>2</dbid>
            <value>Owner</value>
        </data-detail-value>
    </list>
</profile>


<list xid="data.table.head">
  <head-value>
    <name>Area<name>
    <dbid>3</dbid>
  </head-value>
  <head-value>
    <name>Name<name>
    <dbid>1</dbid>
  </head-value>
  <head-value>
    <name>Business<name>
    <dbid>6</dbid>
  </head-value>
  <head-value>
    <name>Tasks<name>
    <dbid>7</dbid>
  </head-value>
  <head-value>
    <name>Ethnicity<name>
    <dbid>8</dbid>
  </head-value>
  <head-value>
    <name>Position<name>
    <dbid>2</dbid>
  </head-value>
</list>

I'm trying to convert this to an excel document. The trouble I am having is that certain data does not always exist for every list. So the columns do not match up appropriately.

I have the following XSLT I'm using to get the table column headers

<xsl:for-each select="list[@xid = 'data.table.head']/head-value">
<xsl:sort select="dbid" data-type="number" /><xsl:value-of select="name"/>,
<xsl:text/></xsl:for-each>

This outputs all of the values of the table header columns like and orders them by dbid

Name | Position | Area | Business | Tasks | Ethnicity

Next part is where I'm stumped. How do I get the data from the list xid data.table to list those values out in the corresponding columns like so,

Name     | Position | Area     | Business        | Tasks       |  Ethnicity

Tim                   New York   Drex Technology                  Spanish
Bethany    Owner                                   Regulations

I'm able to get it to work when all the values are present but when some data is not available in the XML, I run into issues. Ie "New York" appears under "Position."

Thanks in advance for the help.

with this XSLT,

<xsl:stylesheet  version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:variable name="header" select="root/list[@xid='data.table.head']"/>

<xsl:template match="root">
    <table>
        <xsl:apply-templates select="list[@xid = 'data.table.head']"/>
        <xsl:apply-templates select="profile"/>
    </table>
</xsl:template>

<xsl:template match="profile">
    <tbody>
        <xsl:apply-templates/>
    </tbody>
</xsl:template>

    <xsl:template match="list[@xid = 'data.table.head']">
        <thead>
            <tr>
                <xsl:for-each select="descendant::head-value">
                    <xsl:sort select="dbid" data-type="number" />
                    <td><xsl:value-of select="name"/></td>
                </xsl:for-each>
            </tr>
        </thead>
    </xsl:template>

    <xsl:template match="profile/list[@xid = 'data.table']">
        <xsl:variable name="cell_data" select="descendant::data-detail-value"/>
        <tr>
        <xsl:for-each select="$header/head-value">
            <xsl:sort select="dbid" data-type="number" />
            <xsl:choose>
                <xsl:when test="current()/dbid=$cell_data/dbid">
                    <td><xsl:value-of select="$cell_data/value[preceding-sibling::dbid=current()/dbid]"/></td>
                </xsl:when>
                <xsl:otherwise>
                    <td/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
        </tr>
    </xsl:template>

</xsl:stylesheet>

when applied with with this input:

it outputs

<table>
    <thead>
        <tr>
            <td>Name</td>
            <td>Position</td>
            <td>Area</td>
            <td>Business</td>
            <td>Tasks</td>
            <td>Ethnicity</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Tim</td>
            <td></td>
            <td>New York</td>
            <td>Drex Technology</td>
            <td></td>
            <td>Spanish</td>
        </tr>
        <tr>
            <td>Bethany</td>
            <td>Owner</td>
            <td></td>
            <td></td>
            <td>Regulation</td>
            <td></td>
        </tr>
    </tbody>
</table>

maybe you can adapt this approach to your current problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM