xsltdescendant

XSLT: How do I match every descendant individually?


I am attempting to flatten the following XML:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://pretend.namespace">
    <record>
        <first>1</first>
        <second>2</second>
        <tricky>
            <taxing>3</taxing>
            <mayhem>
                <ohno>4</ohno>
                <boom>5</boom>
            </mayhem>
        </tricky>
    </record>
    <record>
        <first>1</first>
        <second>2</second>
        <tricky>
            <taxing>3</taxing>
            <mayhem>
                <ohno>4</ohno>
                <boom>5</boom>
            </mayhem>
        </tricky>
    </record>
    <record>
        <first>1</first>
        <second>2</second>
        <tricky>
            <taxing>3</taxing>
            <mayhem>
                <ohno>4</ohno>
                <boom>5</boom>
            </mayhem>
        </tricky>
    </record>
</root>

into one row-per record, discarding the complex structure within the records.

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5

using this XSLT

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:p="http://pretend.namespace">

<xsl:strip-space elements="*"/> <!-- remove unwanted whitespace? -->

 <!-- Match every p:record -->
<xsl:template match="p:record">
    <xsl:apply-templates/> <!-- now we're inside a <record> do what you can with the contents then give a line return -->
    <xsl:text>&#xA;</xsl:text><!-- this is a line return -->
</xsl:template>

<xsl:template match="p:record//*">
    <xsl:value-of select="."></xsl:value-of><xsl:text>,</xsl:text>
</xsl:template>

<xsl:template match="text()"/> <!-- WORKS: prevents "default output" to aid debugging -->

</xsl:stylesheet>

but despite hours of trying I cannot get it to visit each descendant and comma-separate them all, and I get this:

1,2,345,
1,2,345,
1,2,345,

What do I need to do to get it to treat all the grandchildren and below individually? (The final comma per line isn't an issue)

Thank you!

EDIT: The discussion following this question indicated that Dr. Herong Yang's XML Tools for Notepad++ appears to only support XSLT 1.0


Solution

  • Why not simply

    <xsl:strip-space elements="*"/>
    <xsl:template match="record">
      <xsl:value-of select="descendant::text()/data()" separator=","/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:template>
    

    (The explicit atomization using data() is needed because otherwise, adjacent text nodes are concatenated without a separator).