Recently, I learned what Clark notation is in XML. If the XML looks something like this:
<srw:searchRetrieveResponse
xmlns:srw="http://www.loc.gov/zing/srw/"
...
<srw:record>
...
<dc:title>The C programming language</dc:title>
...
</srw:record>
With lxml in Python, you can parse it like this:
record_title = r.find('.//{http://purl.org/dc/elements/1.1/}title')
The construction .//{namespace uri}tag name was new to me. I think it's very useful with datasets you're not familiar with, because you only need to know the name space uri (which is in the XML header), the prefix and the tag name, to find it. So there's no need to know your way around the XML-tree.
Now, I usually write XSL for XML using a browser: just specify the XSL-sheet at the top in your sample XML-file, doubleclick it and the browser will show what your XSL made of it. So can I use Clark notation in XSL/XSLT? As far as I could find out, the answer is no. Some Googling led me to libraries for PHP and Perl that support it, but apparently, XSLT does not.
Did I miss something? If I didn't, what could be the reason(s) that XSLT doesn't support it?
Well, a path like .// or let's better say starting with .// is supported in any XSLT/XPath version (https://www.w3.org/TR/xpath-10/#path-abbrev).
For standardized support based on the Clark notation you need to turn to XPath/XSLT 3 https://www.w3.org/TR/xpath-31/#doc-xpath31-URIQualifiedName where it is done as Q{http://example.com}foo to select elements with local name foo in the namespace http://example.com.
And of course neither that syntax nor your one uses any prefix, it directly uses the namespace instead of any prefix. Using a prefix e.g. pf:foo is supported in any version of XSLT/XPath, in XSLT you simply need to make sure the stylesheet binds the prefix with e.g. xmlns:pf="http://example.com" to the right namespace, with XPath it depends on the particular API whether and how you can do that.
Here is an example based on your input to show some options you have in XSLT 3:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<four-ways-to-select>
<enhanced-qname>
<xsl:copy-of select="//Q{http://purl.org/dc/elements/1.1/}title"/>
</enhanced-qname>
<namespace-declaration>
<xsl:copy-of select="//dc:title" xmlns:dc="http://purl.org/dc/elements/1.1/"/>
</namespace-declaration>
<xpath-default-namespace>
<xsl:copy-of select="//title" xpath-default-namespace="http://purl.org/dc/elements/1.1/"/>
</xpath-default-namespace>
<namespace-wildcard>
<xsl:copy-of select="//*:title"/>
</namespace-wildcard>
</four-ways-to-select>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3NJ38Z2
The notation in your example
'.//{http://purl.org/dc/elements/1.1/}title'
is not supported in any version of XPath, but XPath 3.0 offers something very similar, namely
'.//Q{http://purl.org/dc/elements/1.1/}title'
The reason for not using Clark notation unchanged is that there were many competing proposals at the time for expressions starting with "{", including maps in JSONiq, statement blocks in the XQuery scripting language, and short-form inline functions; there was also a risk of confusion with the use of "{" in XSLT attribute value templates.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With