I have a following XML file:
<titles>
<book title="XML Today" author="David Perry"/>
<book title="XML and Microsoft" author="David Perry"/>
<book title="XML Productivity" author="Jim Kim"/>
<book title="XSLT 1.0" author="Albert Jones"/>
<book title="XSLT 2.0" author="Albert Jones"/>
<book title="XSLT Manual" author="Jane Doe"/>
</titles>
I want to eliminate some elements and apply the following XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="author1-search" match="book[starts-with(@author, 'David')]" use="@title"/>
<xsl:template match="book [key('author1-search', @title)]" />
<xsl:key name="author2-search" match="book[starts-with(@author, 'Jim')]" use="@title"/>
<xsl:template match="book [key('author2-search', @title)]" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
Is it possible to use an inline xsl variable
<xsl:variable name="Author">
<name>David</name>
<name>Jim</name>
</xsl:variable>
instead of “author1-search”, “author2-search”, and so on to loop through names?
I can use only XSLT 1.0 (2.0 is currently not supported).
Thanks in advance,
Leo
No, patterns (in XSLT 1.0) cannot contain variable/parameter references.
One way to perform such a task would be like this:
When this transformation is applied on the provided XML document:
the wanted, correct result is produced:
Update: In a comment the OP has clarified that:
Here is a solution that truly uses keys (note that the “key” in the answer by @Flynn1179 doesn’t build any index and is just a constant sequence of strings– so the function
key()using thatxsl:keyis actually finding a string in a list of strings — which is O(N) as contrasted to, typically, O(1) for searching in a true index):When this transformation is applied to the provided XML document (above), the wanted, correct result is produced:
Do note: In this solution the Exslt function
node-set()is used. This is done only for convenience here. In a real usage, the value of the parameter will be specified externally and then theext:node-set()function isn’t necessary.Efficiency: This solution uses the true power of keys in XSLT. An experiment made using MSXML (3, 4 and 6) XSLT processors shows that if we search for 10000 authors the transformation time with different XSLT processors ranges from: 32ms to 45ms.
Interestingly, the solution presented by @Flynn1179 doesn’t indeed make key index and with many XSLT processors it takes (for the same number (10000) of authors) from 1044ms to 5564ms:
MSXML3: 5564 ms.,
MSXML4: 2526ms,
MSXML6: 4867 ms,
AltovaXML: 1044ms.
This is quite inferior to the performance one gets with true key indexing (32ms to 45ms).