Why do text nodes appear in transformed xml

2020-05-07 06:43发布

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 ;-)

标签: xml xslt
2条回答
Anthone
2楼-- · 2020-05-07 07:15

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>
查看更多
走好不送
3楼-- · 2020-05-07 07:27

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

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

to your stylesheet.

查看更多
登录 后发表回答