xmlxsltrowset

xslt skip schema in rowset


I have the following questions or problems with my xsl below. I've included my current output, the xml and the xsl. I'm having issues trying to remove the 2nd line containing the double quotes. I'm assuming it is coming from the schema node.

1) the closest version my xsl puts an invalid line between the headings and the data as show in the sample below.
2) I tried inserting this template "" before the 2nd template to remove the blank line caused by the schema node but it had no effect
3) I tried changing the 2nd template to look like this 1]/child::"> but it messes up the formatting of my data. I don't quite understand why because >0 works fine.
4 I also tried changeing the 2nd template with variations of match="Row/child::
but this also messes up the format of the data. Any help is greatly appreciated.

Current Results:

"Column0", "Column1", "Column2", "Column3"
""
"0",    "2010",    "336227.46",    "1.43075514893617"
"0",    "2011",    "782819.36",    "3.40356243478261"
"0",    "2012",    "783044.89",    "3.33210591489362"

Source XML:

<rowset xmlns="urn:schemas-microsoft-com:xml-analysis:rowset" >
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:saw-sql="urn:saw-sql" targetNamespace="urn:schemas-microsoft-com:xml-analysis:rowset">
        <xsd:complexType name="Row">
            <xsd:sequence>
                <xsd:element name="Column0" type="xsd:int" minOccurs="0" maxOccurs="1" saw-sql:type="integer" saw-sql:displayFormula="s_0" />
                <xsd:element name="Column1" type="xsd:string" minOccurs="0" maxOccurs="1" saw-sql:type="varchar" saw-sql:displayFormula="s_1" />
                <xsd:element name="Column2" type="xsd:double" minOccurs="0" maxOccurs="1" saw-sql:type="double" saw-sql:displayFormula="s_2" />
                <xsd:element name="Column3" type="xsd:double" minOccurs="0" maxOccurs="1" saw-sql:type="double" saw-sql:displayFormula="s_3" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:schema>
    <Row>
        <Column0>0</Column0>
        <Column1>2010</Column1>
        <Column2>336227.46</Column2>
        <Column3>1.43075514893617</Column3>
    </Row>
    <Row>
        <Column0>0</Column0>
        <Column1>2011</Column1>
        <Column2>782819.36</Column2>
        <Column3>3.40356243478261</Column3>
    </Row>
    <Row>
        <Column0>0</Column0>
        <Column1>2012</Column1>
        <Column2>783044.89</Column2>
        <Column3>3.33210591489362</Column3>
    </Row>
</rowset>

Code Version - Closest

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
    xmlns:err="http://www.w3.org/2005/xqt-errors"
    exclude-result-prefixes="xs xdt err fn">

    <xsl:output method="text" indent="yes"/>

<xsl:strip-space elements="*" />

<xsl:template match="/*">
<xsl:for-each select="*[2]/*">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>"</xsl:text>
<xsl:if test="position() != last()">, </xsl:if>
<xsl:if test="position() = last()">
<xsl:text>&#xD;&#xA;</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>


<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()">"<xsl:value-of select="normalize-space(.)"/>",    </xsl:if>
<xsl:if test="position()  = last()">"<xsl:value-of select="normalize-space(.)"/>"<xsl:text>&#xD;&#xA;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Solution

  • The extra line is caused by your applying templates to all children of the root element. This includes the xsd:schema node.

    You can prevent this by changing:

    <xsl:apply-templates/>
    

    in line #23 to:

    <xsl:apply-templates select="*[position() gt 1]"/>
    

    P.S. I would suggest you use explicit names to address the source XML nodes, instead of cryptic abbreviations like *[2]/*. That will make your code more readable and - as a result - easier to manage.