I am trying to print the fruit names which is not in the data:fruit
. In my case I expect Pineapple, Kiwi
. I am accessing the data:fruit
in the XSLT xml configuration by 'select="document('')/*/data:fruit/attribute/@value"'
. Currently I am getting the following error.
Error:
Error executing XSLT at line 24 : Exception thrown by URIResolver resolving `` against `'. Found while atomizing the first argument of fn:string-join()
Please check the following xsltfiddle link: https://xsltfiddle.liberty-development.net/jyfAiC7/4
xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:set="http://exslt.org/sets"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="exsl"
version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<data:fruit>
<attribute value="Pineapple" />
<attribute value="Kiwi" />
<attribute value="Apple" />
<attribute value="Orange" />
<attribute value="Banana" />
<attribute value="Cherry" />
<attribute value="Peach" />
</data:fruit>
<xsl:template match="/">
<xsl:variable name="fruitMissing">
<xsl:for-each select="document('')/*/data:fruit/attribute/@value">
<xsl:variable name="fruit" select="."/>
<xsl:if test="count(//root/details/item/line[contains(.,$fruit)])=0"><xsl:value-of select="."/>,</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$fruitMissing"/>
</xsl:template>
</xsl:stylesheet>
xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<header/>
<details>
<item>
<line>14.04.22 5:04:30;Apple;Finished</line>
</item>
<item>
<line>14.04.22 3:36:42;Apple;Finished</line>
</item>
<item>
<line>14.04.22 4:03:47;Orange;Finished</line>
</item>
<item>
<line>14.04.22 2:40:33;Orange;Finished</line>
</item>
<item>
<line>14.04.22 3:37:12;Banana;Finished</line>
</item>
<item>
<line>14.04.22 3:36:59;Cherry;Finished</line>
</item>
<item>
<line>14.04.22 3:36:57;Peach;Finished</line>
</item>
</details>
<summary/>
<statistics/>
<exceptions/>
</root>
CodePudding user response:
I would suggest you do it this way:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="existing-fruit" match="item" use="tokenize(line, ';')[2]" />
<xsl:variable name="fruit">
<attribute value="Pineapple" />
<attribute value="Kiwi" />
<attribute value="Apple" />
<attribute value="Orange" />
<attribute value="Banana" />
<attribute value="Cherry" />
<attribute value="Peach" />
</xsl:variable>
<xsl:template match="/" >
<xsl:variable name="xml" select="." />
<xsl:value-of select="$fruit/attribute[not(key('existing-fruit', @value, $xml))]/@value" separator=","/>
</xsl:template>
</xsl:stylesheet>
Beside being shorter and more efficient, it also avoids possible false positive match on other values included in line
.
Demo: https://xsltfiddle.liberty-development.net/jyfAiC7/5
CodePudding user response:
Try this XSLT2:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:set="http://exslt.org/sets"
xmlns:data="http://mulocal/host"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="exsl"
version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<data:fruit>
<attribute value="Pineapple" />
<attribute value="Kiwi" />
<attribute value="Apple" />
<attribute value="Orange" />
<attribute value="Banana" />
<attribute value="Cherry" />
<attribute value="Peach" />
</data:fruit>
<xsl:template match="/">
<xsl:variable name="varInput" select="root"/>
<xsl:for-each select="document('')/*/data:fruit/attribute/@value">
<xsl:variable name="fruit" select="."/>
<xsl:if test="count($varInput/details/item/line[contains(.,$fruit)])=0">
<xsl:value-of select="."/><xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Result:
<?xml version="1.0" encoding="UTF-8"?>Pineapple,Kiwi,