XSL for-each and value-of - xslt

Given the xml:
<element>text</element>
...
<element>text</element>
And xsl:
<xsl:for-each select="element">
...
</xsl:for-each>
What do I need to put inside the for-each loop to access the text? There doesn't seem to be a corresponding xsl:value-of because select="", select="/", and select="element" are all wrong.

<xsl:value-of select="."/>

Related

My XSLT Variable doesn't load in template

So I'm trying to create a variable and then later on use this in my template.
This is the code I have now:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="items">
<xsl:call-template name="item" />
</xsl:template>
<xsl:template name="item">
<xsl:for-each select="item">
<xsl:variable name="currentItemTheme">
test variable
</xsl:variable>
<xsl:if test="title = name">
Showvariable: {$currentItemTheme} <br/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I have no idea why it doesn't work. My file does output the "Showvariable: ", but it just doesn't show the test values. So the for-each loops and template aren't the problem.
Is there something I'm missing? Does someone know how I get this to work?
I think you want <xsl:value-of select="$currentItemTheme"/> instead of {$currentItemTheme}, unless you are mixing the XSLT code with some other language that provides the {$currentItemTheme} syntax.
<xsl:copy-of select="$currentItemTheme"/> is another option if you build nodes in your variable and want to output them instead of just the string value as a text node.

How to pass variable name inside for-each loop in xslt

I'm new to Xslt I'm reading xml data using xslt. for example
<head>
<root>
<data>
<Name>xxx</Name>
<age>10</age>
</data>
<data>
<Name>yyy</Name>
<age>20</age>
</data>
<data>
<Name>zzz</Name>
<age>15</age>
</data>
</root>
</head>
When I tried use below xslt
<xsl:template match="head">
<xsl:element name="Root1">
<xsl:for-each select="//head/root/data">
<xsl:element name="name">
<xsl:value-of select="$select_Name"/>
</xsl:element>
<xsl:element name="age">
<xsl:value-of select="$select_age"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
My c# code is
XslTransform xsl=new XslTransform();
xsl.Load("xsltfile");
xsl.Transform("inputxml.xml","outputxml.xml");
I'm not getting proper output when i use the above xslt file. whereas when I give the xpath of the element to a variable in another xslt file and include the xslt into this xslt and pass variable name instead of hardcoded value <xsl:value-of select="$select_Name"/> like this whereas $name is declared as <xsl:variable name="select_Name" select="//head/root/data/Name"/> im getting the value of name for the field of Age. Anyone faced this kind of issue? or can you share how to pass the variable name instead of element name for the value inside for-each loop?

Seperate attribute values with comma in xslt 1.0?

My source XML:-
<wireframe:xaIDExclusion>
<widget:xaID id="12"/>
<widget:xaID id="121"/>
<widget:xaID id="123"/>
<widget:xaID id="124"/>
<widget:xaID id="3456"/>
</wireframe:xaIDExclusion>
This is what i tried
<xsl:template match="widget:xaID">
<xsl:element name="xaid">
<xsl:variable name ="value" select="#id"></xsl:variable>
<xsl:value-of select="concat($value,',')"></xsl:value-of>
</xsl:element>
</xsl:template>
I need output like this,how to do that
12,121,123,124,3456
Thanks in advance
The problem with your approach is that you're matching widget:xaID and then creating a xaid element; this results in multiple xaid elements, one for each widget:xaID. You need to create the xaid element while you are in the context of the parent of widget:xaID.
Try (untested, because you did not provide a well-formed XML):
<xsl:template match="wireframe:xaIDExclusion">
<xaid>
<xsl:for-each select="widget:xaID">
<xsl:value-of select="#id">
<xsl:if test="position()!=last()">, </xsl:if>
</xsl:for-each>
</xaid>
</xsl:template>

XSLT 1.0: if statement when position matches a variable value

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>

Nested for-each loops, accessing outer element with variable from the inner loop

I'm trying to write an XSL that will output a certain subset of fields from the source XML. This subset will be determined at transformation time, by using an external XML configuration document containing the field names, and other specific information (such as the padding length).
So, this is two for-each loops:
The outer one iterates over the records to access their fields record by record.
The inner one iterates over the configuration XML document to grab the configured fields from the current record.
I've seen in In XSLT how do I access elements from the outer loop from within nested loops? that the current element in the outside loop can be stored in an xsl:variable. But then I've got to define a new variable inside the inner loop to get the field name. Which yields to the question: Is it possible to access a path in which there are two variables ?
For instance, the source XML document looks like:
<data>
<dataset>
<record>
<field1>value1</field1>
...
<fieldN>valueN</fieldN>
</record>
</dataset>
<dataset>
<record>
<field1>value1</field1>
...
<fieldN>valueN</fieldN>
</record>
</dataset>
</data>
I'd like to have an external XML file looking like:
<configuration>
<outputField order="1">
<fieldName>field1</fieldName>
<fieldPadding>25</fieldPadding>
</outputField>
...
<outputField order="N">
<fieldName>fieldN</fieldName>
<fieldPadding>10</fieldPadding>
</outputField>
</configuration>
The XSL I've got so far:
<xsl:variable name="config" select="document('./configuration.xml')"/>
<xsl:for-each select="data/dataset/record">
<!-- Store the current record in a variable -->
<xsl:variable name="rec" select="."/>
<xsl:for-each select="$config/configuration/outputField">
<xsl:variable name="field" select="fieldName"/>
<xsl:variable name="padding" select="fieldPadding"/>
<!-- Here's trouble -->
<xsl:variable name="value" select="$rec/$field"/>
<xsl:call-template name="append-pad">
<xsl:with-param name="padChar" select="$padChar"/>
<xsl:with-param name="padVar" select="$value"/>
<xsl:with-param name="length" select="$padding"/>
</xsl:call-template>
</xsl:for-each>
<xsl:value-of select="$newline"/>
</xsl:for-each>
I'm quite new to XSL, so this might well be a ridiculous question, and the approach can also be plain wrong (i.e. repeatig inner loop for a task that could be done once at the beggining). I'd appreciate any tips on how to select the field value from the outer loop element and, of course, open to better ways to approach this task.
Your stylesheet looks almost fine. Just the expression $rec/$field doesn't make sense because you can't combine two node sets/sequences this way. Instead, you should compare the names of the elements using the name() function. If I understood your problem correctly, something like this should work:
<xsl:variable name="config" select="document('./configuration.xml')"/>
<xsl:for-each select="data/dataset/record">
<xsl:variable name="rec" select="."/>
<xsl:for-each select="$config/configuration/outputField">
<xsl:variable name="field" select="fieldName"/>
...
<xsl:variable name="value" select="$rec/*[name(.)=$field]"/>
...
</xsl:for-each>
<xsl:value-of select="$newline"/>
</xsl:for-each>
Variable field is not required in this example. You can also use function current() to access the current context node of the inner loop:
<xsl:variable name="value" select="$rec/*[name(.)=current()/fieldName]"/>