Why do text nodes appear in transformed xml

2020-05-07 07:22发布

问题:

I want to use xslt to select some node-sets with a specific value in an element from an xml-file. I do get the node I want, but I also get some the serialized text from textnodes. Can you please help me to get rid of this text?

This is the source file:

<surveys>
<survey id='01'>
    <category>cat1</category>
    <questions>
        <question id='1'>Y</question>
        <question id='2'>Y</question>
        <question id='3'>Y</question>
        <question id='4'>Y</question>
    </questions>
</survey>
<survey id='02'>
    <category>cat2</category>
    <questions>
        <question id='1'>Y</question>
        <question id='2'>Y</question>
        <question id='3'>N</question>
        <question id='4'>N</question>
    </questions>
</survey>
<survey id='03'>
    <category>cat1</category>
    <questions>
        <question id='1'>N</question>
        <question id='2'>N</question>
        <question id='3'>N</question>
        <question id='4'>N</question>
    </questions>
</survey>
<survey id='04'>
    <category>cat3</category>
    <questions>
        <question id='1'>N</question>
        <question id='2'>N</question>
        <question id='3'>Y</question>
        <question id='4'>Y</question>
    </questions>
</survey>
</surveys>

This is the transform file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
    <surveys>
        <category/>
        <xsl:apply-templates/>
    </surveys>
</xsl:template>

<xsl:template match="survey[category = 'cat2']">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

And this the result:

<surveys>cat1YYYY<survey id="02">
    <category>cat2</category>
    <questions>
        <question id="1">Y</question>
        <question id="2">Y</question>
        <question id="3">N</question>
        <question id="4">N</question>
    </questions>
</survey>cat1NNNNcat3NNYY</surveys>

So, I'd like to get rid of "cat1YYYY" in the first line after the surveys element and of "cat1NNNNcat3NNYY" in the last line after the survey element. And I'd like to understand why it's there ;-)

回答1:

I'd like to understand why it's there

It's there because you are applying templates indiscriminately - and XSLT has some built-in template rules that copy text nodes as the default.

To prevent this from happening, you could add your own template to override the default behavior:

<xsl:template match="text()" />

or - preferably - apply templates selectively to begin with:

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

<xsl:template match="/surveys">
    <surveys>
        <category/>
        <xsl:apply-templates select="survey[category = 'cat2']"/>
    </surveys>
</xsl:template>

<xsl:template match="survey">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

which BTW could be shortened to:

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

<xsl:template match="/surveys">
    <surveys>
        <category/>
        <xsl:copy-of select="survey[category = 'cat2']"/>
    </surveys>
</xsl:template>

</xsl:stylesheet>


回答2:

You could send the superfluous text() nodes to oblivion by adding

<xsl:template match="text()" />

to your stylesheet.



标签: xml xslt