XSLT Built-in Template Rules for Attributes

I am sure this is a very simple question, but it doesn’t matter here! I read that the built-in template rule for text and attribute nodes in XSLT

<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template> 

However, for the original document

 <?xml version="1.0"?> <booker> <award> <author blah="test">Aravind Adiga</author> <title>The White Tiger</title> <year>2008</year> </award> </booker> 

And XSLT

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

I get the following result by applying a transform in Visual Studio. Can someone explain why I do not see the “test” on the output?

Aravdin Adiga

White tiger

2008

+7
xslt
source share
3 answers

Since the built-in rule for elements does not apply templates to elements of their own attributes, only children are related to them. If you want to move attributes the same way you go through child elements (which is probably an artificial task), you need to define your own by default:

 <xsl:template match="*"> <xsl:apply-templates select="@*"/> <xsl:apply-templates/> </xsl:template> 
+6
source share

To answer this question from a comment:

Thanks, I don’t need to do this, I’m just trying to understand the rules. So the main body of the @ * built-in rule will never be called unless explicitly specified?

In this case, there are two default rules that interest us:

 <xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="/|*"> <xsl:apply-templates/> </xsl:template> 

When the document is processed, the second template corresponds to the root and the templates are applied. The default for apply templates is to select all child nodes (attributes, confusing, are not child nodes). You never select any attribute that should be processed, since it uses only apply-templates by default.

So, if you select any attribute (for example, Vincent Marchetti), it will be processed by the first template mentioned by default.

+6
source share

The basic rule: attributes do not have an identifier at all - they are only available as side bits bound to a node . It’s good to think of them as non-existent until you have a node. You can also think of them as second-class citizens in the world of XPath and XSLT. Each time you use them in the selection conditions, you, as you switch from join to cursor in SQL, and every time you use "for" instead of "apply", this also happens.

Another way to express this is the only real, effective “index” that you have, one that has all the XPaths in the document (.Net actually creates a Hashtable from XPaths => constant time). The reason for “applying” the privilege is that it guarantees pure functional processing — you can run everything that corresponds to the application on separate threads without synchronization and without memory exchange — you simply agree with their results.

The third way to look at this, which is stretching, is to imagine that your tags are SQL tables, and that you only have surrogate PKs and FKs - you can’t choose anything else but “all of T1 and all related to them from T2. " For any worthy SQL engine, this seems like a 0-time effort to do this - it just reads one good index element by position, as its structure is 1-1 with your query. Everything else costs a lot more.

Once you have selected the tags and matched the templates and executed them, then it’s cheap for you to simply get the attribute values ​​- for now, you just transform / render them. Attrib tests at the end of XPath are also quite cheap - again, since the last / node tag is selected, and now it just filters a little on top of it.

So, the XSLT engine and XPath choice generally have a very good reason to completely ignore attributes - perf.

+2
source share

All Articles