XSLT default template confusion

2019-05-23 14:58发布

问题:

I'm getting a confusion on the way XSLT processors nodes, suppose I have an XML Doc like this:

<object>
        <animal>
                <man men="asd">man1</man>
                <man>man2</man>
                <man>man3</man>
                <man>man4</man>
                <cat>cat1</cat>
                <cat>cat2</cat>
                <cat>cat3</cat>
                <cat>cat4</cat>
        </animal>
        <vehicule>
                <car>car1</car>
                <car>car2</car>
                <car>car3</car>
                <car>car4</car>
        </vehicule>
</object>

When I have an XSLT without any template matching like the one below, it returns all text nodes and no attribute nodes, that's OK

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

But when I have one like the one below, it doesn't return anything:

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

Is it that if I have an explicit template for a parent node, I should have an explicit template for all child nodes of the parent nodes?

回答1:

What you are seeing are simply the effects of the built-in rules, which output the text value of a node and apply the templates to all its children.

If you overwrite the built-in templates, well, your template takes effect. You want to apply the built-in rules for all children of object:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="object">
    <xsl:apply-templates select="*" />
  </xsl:template>
</xsl:stylesheet>


回答2:

Your rule in #2 says to do nothing, so it did nothing. You need to write something in there. See xsl:copy and xsl:apply-templates.



回答3:

http://cafeconleche.org/books/xmljava/chapters/ch17.html#d0e31297

As others have said, the XSLT default template rules are defined in such a way that, by default, they will match the top node of the document and then recursively process each of the child nodes, all the way to the bottom. Your template overrides the default rules for the root node, and doesn't have any instructions to do anything with it, so it doesn't go any further. If you instead had this:

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

It would continue processing on downwards, using the default rules. You don't necessarily need to do anything specific to handle the child nodes as long as you send the processing their way.



标签: xslt