I have a xslt document. And i want use if statement in this document. My code is:
<xsl:for-each select="cbc:ProfileID">
<xsl:apply-templates/>
<xsl:if test="cbc:ProfileID='code1'">
<xsl:text>A</xsl:text>
</xsl:if>
<xsl:if test="cbc:ProfileID='code2'">
<xsl:text>B</xsl:text>
</xsl:if>
</xsl:for-each>
I want if returned value is code1 then write A and if returned value is code2 then write B.
How can i do this?
As i can understand you are already in the same context by for-each so you need to use . in if condition like below:
<xsl:if test="normalize-space(.)='code1'">
or
<xsl:if test=".='code1'">
Related
Is there a way to gather element name of a tokenized value? I have been trying to do it but it is giving me an error "[Saxon-PE 9.6.0.7] XPTY0004: Required item type of first argument of name() is node(); supplied value has item type xs:string"
Here are my sample set of data:
<SET>
<REAL_TAGNAME> 1 2 3 4 </REAL_TAGNAME>
</SET>
If I have use this code:
<xsl:for-each select="SET/REAL_TAGNAME">
<xsl:for-each select="tokenize(normalize-space(.),'\s+')">
<Hardcode_Tag>
<xsl:value-of select="."/>
</Hardcode_Tag>
</xsl:for-each>
</xsl:for-each>
then I will successfully have the following:
<Hardcode_Tag>1</Hardcode_Tag>
<Hardcode_Tag>2</Hardcode_Tag>
<Hardcode_Tag>3</Hardcode_Tag>
<Hardcode_Tag>4</Hardcode_Tag>
But I want to move away from hard-coding and would like to use its original tag name to have something like:
<REAL_TAGNAME>1</REAL_TAGNAME>
<REAL_TAGNAME>2</REAL_TAGNAME>
<REAL_TAGNAME>3</REAL_TAGNAME>
<REAL_TAGNAME>4</REAL_TAGNAME>
While I try below with the xsl:element, it keeps giving me an error mentioned above:
<xsl:for-each select="SET/REAL_TAGNAME">
<xsl:for-each select="tokenize(normalize-space(.),'\s+')">
<xsl:element name="{name(.)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
does anyone have any idea on how I can fix this? Thanks in advance for your help!
Within the xsl:for-each, the expression . refers to the current item, i.e. the current token extracted from the string value of the element. If you want to remember the name of the element that was the current element before you entered the for-each, just set a variable before the inner xsl:for-each:
<xsl:for-each select="SET/REAL_TAGNAME">
<xsl:variable name="element-name" select="name(.)"/>
<xsl:for-each select="tokenize(normalize-space(.),'\s+')">
<xsl:element name="{$element-name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
In the code you show, of course, the value of $element-name will invariably be 'REAL_TAGNAME'. I'm assuming that's not true in the general case.
Am getting duplicates in the list, SO i wanted to make distinct .
Workflow Type (
<xsl:for-each select="//Bonaire/RBS/WorkflowTypeList">
<xsl:if test="#BSSLOOKUPTYPEID=//Bonaire/Request/#TYPE_BSSLOOKUPTYPEID">
<xsl:value-of select="#TYPENAME"/>
</xsl:if>
</xsl:for-each>
)
That can be done in a one-liner using distinct-values() and predicate expression ([...]) :
<xsl:for-each select="distinct-values(//Bonaire/RBS/WorkflowTypeList[#BSSLOOKUPTYPEID=//Bonaire/Request/#TYPE_BSSLOOKUPTYPEID]/#TYPENAME)">
<xsl:value-of select="."/>
</xsl:for-each>
I like to create a variable which contains the full PACKAGE name path for corresponding element. (just to be able to compare paths later)
Now I have XSLT structure:
<xsl:for-each select="ancestor-or-self::*">
<xsl:if test="local-name()='PACKAGE'">
<xsl:text>/</xsl:text>
<xsl:value-of select="NAME/."/>
<xsl:if test="position() != last()">
</xsl:if>
</xsl:if>
</xsl:for-each>
This above structure results me the correct path, but when I try to put that output to the variable (by placing the <xsl:variable name="myPath"> and </xsl:variable> outside the foreach) variable stays empty.
So why in:
<xsl:variable name="myPath">
<xsl:for-each select="ancestor-or-self::*">
<xsl:if test="local-name()='PACKAGE'">
<xsl:text>/</xsl:text>
<xsl:value-of select="NAME/."/>
<xsl:if test="position() != last()">
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:variable>
$myPath remains empty?
What I am missing here?
Make sure you use that variable somewhere later in your code as otherwise the XSLT processor is free to not execute the code at all. So without seeing more information I assume that Saxon is simply not executing the value of the variable as you don't use it.
I'm trying to insert an IF statement into an existing FOR-EACH loop to do something slightly different if it matches a variable from another node (the node I want is actually a sibling of it's parent - if that makes sense!?).
The value is a simple integer. I basically want to say: If the position is equal to the variable number then do XXXX.
Here is the XSLT, it's only v1.0 and not 2.0 that I can use.
<xsl:for-each select="/Properties/Data/Datum[#ID='ID1']/DCR[#Type='accordion_tab']/accordion_tab/sections">
<h3 class="accordionButton">
<xsl:if test="position()='openpane value to go here'">
<xsl:attribute name="class">
<xsl:text>new text</xsl:text>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
My XML extract is here:
<sections>
<title>title</title>
<text>some text</text>
</sections>
<openpane>2</openpane>
You didn't make this clear in your question, but I assume you iterate over the sections elements in your for-each loop. From the for-each loop you can reach the openpane element by going through the parent of the current sections element:
<xsl:for-each select="sections">
<xsl:if test="position() = ../openpane">
...
</xsl:if>
</xsl:for-each>
You could also define a variable referring to the openpane element first:
<xsl:variable name="openpane" select="openpane"/>
<xsl:for-each select="sections">
<xsl:if test="position() = $openpane">
...
</xsl:if>
</xsl:for-each>
I have a variable in XSLT called variable_name which I am trying to set to 1, if the Product in question has attributes with name A or B or both A & B.
<xsl:variable name="variable_name">
<xsl:for-each select="product/attributes">
<xsl:if test="#attributename='A' or #attributename='B'">
<xsl:value-of select="1"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
Is there any way to match multiple strings using the if statement, as mine just matches if A is present or B is present. If both A & B are present, it does not set the variable to 1. Any help on this would be appreciated as I am a newbie in XSLT.
You can use xsl:choose statement, it's something like switch in common programming languages:
Example:
<xsl:variable name="variable_name">
<xsl:for-each select="product/attributes">
<xsl:choose>
<xsl:when test="#attributename='A'">
1
</xsl:when>
<xsl:when test=" #attributename='B'">
1
</xsl:when>
<!--... add other options here-->
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
This will set new variable with name variable_name with the value of attribute product/attributes.
For more info ... http://www.w3schools.comwww.w3schools.com/xsl/el_choose.asp
EDIT: And another way (a little dirty) by OP's request:
<xsl:variable name="variable_name">
<xsl:for-each select="product/attributes">
<xsl:if test="contains(text(), 'A') or contains(text(), 'B')">
1
</xsl:if>
</xsl:for-each>
</xsl:variable>
It will be helpful if you provide the xml you're writing your xslt against.
This might not help...
Is it 'legal' to have two XML element attributes with the same name (eg. <element x="1" x="2" />)?
Is this what you are trying to process? Try parsing your XML file through xmllint or something like it to see if it is valid.
xmllint --valid the-xml-file.xml
My guess is that you will get a 'attribute redefined' error.