What is the difference between using XSLT <xsl: element> and declaring elements literally?

I started using XSLT quite recently, and I wonder what the effective difference is between using <xsl:element> to define elements or simply declaring them as literals in XSLT. For example, let's look at a simplified case where I convert the contents of a tiny XML document to (x) HTML.

1. I can go with the <xsl:element> method:

 <xsl:element name="h1"> <xsl:value-of select="heading"/> </xsl:element> 

2. Or define the item manually:

 <h1> <xsl:value-of select="heading"/> </h1> 

What is the actual difference between the two, and is there a difference which one is considered “good”?

+4
source share
4 answers

They are almost identical, the exception is that the literal element <h1> will add namespace nodes that are in scope at this point in the stylesheet to the resulting tree, while <xsl:element name="h1"> will not. The difference in what you do for your output depends on which namespace declarations include your stylesheet and where, if at all, in the result tree. For example, run any XML input document with the following conversion:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://example.com"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <root> <foo:element1 /> <foo:element2 /> </root> </xsl:template> </xsl:stylesheet> 

outputs the following result (using xsltproc):

 <?xml version="1.0"?> <root xmlns:foo="http://example.com"> <foo:element1/> <foo:element2/> </root> 

but changing the <root> literal in the stylesheet to <xsl:element name="root"> instead creates

 <?xml version="1.0"?> <root> <foo:element1 xmlns:foo="http://example.com"/> <foo:element2 xmlns:foo="http://example.com"/> </root> 

since the form <xsl:element> does not attach the namespace "foo" node to the generated element. If that matters, and you really want to copy the style namespace declarations onto the element created with <xsl:element> , you can do this by nesting something like

 <xsl:copy-of select="document('')/*/namespace::foo" /> 

directly inside it (using the document('') idiom, which provides access to the stylesheet XML document itself).

But, as a rule, the main use of <xsl:element> is when the name of the element is computed, and not the letter "compilation-time".

+6
source

xsl: element allows you to define elements whose name you do not know when writing a style sheet, as well as an element whose names are dynamically created. I would always use the built-in definition (i.e. manually), if possible. This is shorter, and I find it more readable.

+4
source

Another technical difference not yet noted in the answers: if you restrict yourself to the xsl:element constructor, your stylesheet may be valid against DTD for XSLT. In some environments (for example, you have an editor that supports DTD), that may be beneficial. However, I have been repeatedly told that no one uses DTD to guide their XSLT construct (except me, that is).

There is also a metaphysical difference (the literal elements of the result can be seen as a form of tag abuse because you use h1 where the value is not “this is the first level heading”, but instead the first level heading here ”), but this is of interest primarily to theorists markup and language designers; I mention this for completeness only.

+1
source

I would strongly advise using literal elements of the result wherever possible .

Therefore, if the name of the element is known in advance (not defined dynamically) and no manipulation of the namespace is required, then use the element of the result literal.

The main advantage of using the literal result element is its readability and less moving parts than compared to xsl:element - this means that it is less error prone .

+1
source

Source: https://habr.com/ru/post/1435970/


All Articles