I am having problems running the next XSL stylesheet:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Blokea">
<xsl:param name="Handiena" select="Blokea/Bl2">
<xsl:if test="Blokea/Bl1>Blokea/Bl2">
<xsl:param name="Handiena" select="Blokea/Bl1">
<xsl:value-of select="$Handiena"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
over the next XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Erroa>
<Blokea>
<Bl1>20</Bl1>
<Bl2>10</Bl2>
</Blokea>
</Erroa>
How can I solve it?
I think what you're trying to do is this:
<xsl:template match="Blokea">
<xsl:param name="Handiena">
<xsl:choose>
<xsl:when test="./Bl1 > ./Bl2">
<xsl:value-of select="./Bl1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./Bl2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:value-of select="$Handiena"/>
</xsl:template>
Correct me if I'm wrong.
Related
I know this is asked before but I can't find a simple example. Just trying to change output format. My existing XSLT is this and works but output format is always .txt.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:text>*,</xsl:text>
<xsl:value-of select="//AccountFields/AccountID"/>
<xsl:text>
</xsl:text>
<xsl:for-each select="//TransactionLine">
<xsl:variable name="i" select="position()" />
<xsl:value-of select="//AccountFields/AccountID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ItemFields/ItemID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="TransactionLineFields/UnitQuantity"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="TransactionLineFields/UnitPrice"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I tried adding <xsl:result-document href="Order.csv" method="text"> but the file fails to generate completely and the tool I'm using doesn't give me a clear way to see errors.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:result-document href="Order.csv" method="text">
<xsl:text>*,</xsl:text>
<xsl:value-of select="//AccountFields/AccountID"/>
<xsl:text>
</xsl:text>
<xsl:for-each select="//TransactionLine">
<xsl:variable name="i" select="position()" />
<xsl:value-of select="//AccountFields/AccountID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="ItemFields/ItemID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="TransactionLineFields/UnitQuantity"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="TransactionLineFields/UnitPrice"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:result-element>
</xsl:template>
</xsl:stylesheet>
xsl:result-document is only available in XSLT 2.0 and later versions.
If you can use XSLT-2.0, you could pass parameters and set the method attribute with an attribute value template to
"xml" | "html" | "xhtml" | "text" | "json" | "adaptive" | eqname
Here, the file extension and the output method are set dynamically by parameters passed to the stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="fileExt" select="'.csv'" />
<xsl:param name="fileMethod" select="'xml'" />
<xsl:template match="/">
<xsl:result-document href="{concat('Order',$fileExt)}" method="{$fileMethod}">
<xsl:text>*,</xsl:text>
...
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
It has been tested with Saxon.
If you wanted to change the xsl:output method instead, have a look at this question.
Here is my input file
<toc-title>(1) Thsi is <content-style>Short title</content-style>
</toc-title>
I want to output as following:
<toctitle>
<label>(1)</label>
<toctext>Thsi is <content-style>Short title</content-style></toctext>
</toctitle>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:template match="toc-title">
<xsl:copy>
<label>
<xsl:value-of select="substring-before(.,' ')"/>
</label>
<toctext>
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="position()=1">
<xsl:value-of select="substring-after(.,' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</toctext>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This iterates thru all child nodes of <toc-title>, assuming that the first child node is always text.
I'm trying to check if two XSL variables are the same:
<?xml version="1.0" encoding="UTF-8"?>
<files>
<file filename="export.csv" path="/export" active="true" ftp="false">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="quote">"</xsl:variable>
<xsl:variable name="sepstart" select="','"/>
<xsl:template match="/">
<xsl:text>"CustomerID"</xsl:text>
<xsl:variable name="second_check">0</xsl:variable>
<xsl:for-each select="orders/order">
<xsl:for-each select="items/item">
<xsl:variable name="output">
<xsl:variable name="first_check"><xsl:value-of select="normalize-space(../../increment_id)"/></xsl:variable>
<xsl:choose>
<xsl:when test="$first_check = $second_check">
Do something...
</xsl:when>
<xsl:otherwise>
Do something...
<xsl:variable name="second_check"><xsl:value-of select="normalize-space(../../increment_id)"/></xsl:variable>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$output" />
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
</file>
</files>
However, it's just skipping over both and not outputting anything.
Can anyone point out what I'm doing wrong?
You cannot "re-declare" variables in XSL. When you write
<xsl:variable name="second_check">
<xsl:value-of select="normalize-space(../../increment_id)"/>
</xsl:variable>
That has no affect, because of this
<xsl:variable name="second_check">0</xsl:variable>
I can't help you though (yet), because I'm not really sure what you're trying to do
e.g i have following strings:
xoc.coe.hw.ZSBALAJI
hw.cor.exp.nt.ZSSHIVA
i have to get only last string (i.e. ZSBALAJI from first and ZSSHIVA from second). How can I do it in xslt.
Thanks in advance.
Here is an XSLT-1.0 solution to your problem:
<?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:template match="//string">
<xsl:call-template name="skipper">
<xsl:with-param name="source" select="."/>
<xsl:with-param name="delimiter" select="'.'"/>
</xsl:call-template>
</xsl:template>
<!-- returns the substring after the last delimiter -->
<xsl:template name="skipper">
<xsl:param name="source"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($source,$delimiter)">
<xsl:call-template name="skipper">
<xsl:with-param name="source" select="substring-after($source,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$source"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
When applied to this document:
<?xml version="1.0" encoding="UTF-8"?>
<strings>
<string>xoc.coe.hw.ZSBALAJI</string>
<string>hw.cor.exp.nt.ZSSHIVA</string>
</strings>
It produces the following result:
ZSBALAJI
ZSSHIVA
Let's assume that you have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>xoc.coe.hw.ZSBALAJI</a>
<a>hw.cor.exp.nt.ZSSHIVA</a>
</root>
Then the following XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="//a">
<xsl:variable name="parts" select="tokenize(node(), '\.')"/>
<xsl:variable name="count" select="count($parts)"/>
<xsl:for-each select="$parts">
<xsl:if test="position() = $count">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
will ouput
ZSBALAJI
ZSSHIVA
Essentially, you can use XPath tokenize function and then take the last token.
You can try and use EXSLT tokenize(string, string?) function to split by '.' on the relevant node, see this for additional info.
An XML file has data like:
<AddtlStsRsnInf>/00000002/Level 2 Reject</AddtlStsRsnInf>
<AddtlStsRsnInf>The Transaction Reference Number is</AddtlStsRsnInf>
<AddtlStsRsnInf>not unique.</AddtlStsRsnInf>
How do you concatenate the data from all the three tags into a variable?
Thanks and regards,
Kiran
This may help:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="concat" match="/data">
<xsl:for-each select="AddtlStsRsnInf">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Given:
<?xml version="1.0"?>
<data>
<AddtlStsRsnInf>/00000002/Level 2 Reject</AddtlStsRsnInf>
<AddtlStsRsnInf>The Transaction Reference Number is</AddtlStsRsnInf>
<AddtlStsRsnInf>not unique.</AddtlStsRsnInf>
</data>
You can wrap it in a variable (v) using:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="concat" match="/data">
<xsl:variable name="v">
<xsl:for-each select="AddtlStsRsnInf">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$v" />
</xsl:template>
</xsl:stylesheet>
I think you would use something like:
<xsl:variable name="myVar" select="fn:string-join(//AddtlStsRsnInf/text(), ' ')" />
You'll need to adjust the XPath query if you're only supposed to select some AddtlStsRsnInf nodes.