Cliff
Cliff

Reputation: 1701

XSLT conditionally write to two different files

I need to extract log meesages from an XML file and write them out to plain text files. The log messages come in two flavors, and I want to write them to separate files.

I have written a style sheet that does exactly what I need except that it sometimes creates empty files because the XML file may not contain messages of one type or another.

I am wondering, 1) if what I ma doing is the best method to do this, and 2) if there is a way to suppress empty files.

My sample may contain errors because it has been retyped. (the original is on a closed network)

Note: I am using XSLT 2.0 features.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output method="text" encoding="iso-8859-1" />

<xsl:param name="break" select="string('&#xA;')" />

<xs:template match="/">

    <xsl:result-document method="text" href="foo.txt">
        <xsl:apply-templates select="Root/a/b/c[contains(., 'foo')]" />
    </xsl:reult-document>

    <xsl:result-document method="text" href="bar.txt">
        <xsl:apply-templates select="Root/a/b/c[not(contains(., 'foo'))]" />
    </xsl:reult-document>

</xsl:template>

<xsl:template match="*">
    <xsl:value-of select=concat(normalize-space(.), $break)" />
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Views: 1246

Answers (1)

user357812
user357812

Reputation:

You could use some XSLT 2.0 stylesheet like:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="break" select="string('&#xA;')" />
    <xsl:template match="/">
        <xsl:apply-templates select="Root/a/b/c"/>
    </xsl:template>
    <xsl:template match="/Root/a/b/c[contains(., 'foo')]">
        <xsl:result-document method="text" href="foo.txt">
            <xsl:next-match/>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="/Root/a/b/c[not(contains(., 'foo'))]">
        <xsl:result-document method="text" href="bar.txt">
            <xsl:next-match/>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="*">
        <xsl:value-of select="concat(normalize-space(.), $break)" />
    </xsl:template>
</xsl:stylesheet>

Note: Pattern matching and xsl:next-match.

Upvotes: 3

Related Questions