I woud like to make some nested loops over my xml doc
Here is my xml
<evolutionlist>
<date id="22_05_2014">
<objet>
<identifier>1VD5-3452-8R5</identifier>
<link>Link1</link>
<title>EXCHANGE OF ELEMENTS</title>
</objet>
<objet>
<identifier>1V24-34A2-8C5</identifier>
<link>Link1</link>
<title>NEW ELEMENT</title>
</objet>
</date>
<date id="21_05_2014">
<identifier>1VV4-34A2-8C5</identifier>
<link>Link2</link>
<title>REPLACE</title>
</date>
</evolutionlist>
Ideally, I woudl like to display something like
22_05_2014
objet1 (with add infos)
objet2 (with add infos)
21_05_2014
objet3 (with add infos)
I made:
<xsl:for-each select="//date">
<xsl:value-of select="#id"/>
<xsl:for-each select="objet">
<tr>
<td>
<xsl:value-of select="identifier"/>
</td>
<td>
<xsl:value-of select="link"/>
</td>
<td>
<xsl:value-of select="title"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
but I got
22_05_2014 21_05_2014
objet1
objet2
objet3
where did I go wrong ?
EDIT
I tried
<xsl:for-each select="./objet">
for the second loop but that did not work either
Shame on me !
I forgot to do this:
<tr>
<td>
<xsl:value-of select="./#id"/>
</td>
</tr>
You were right, Ian Roberts, by encouraging me do write the real code
Related
I have two loops and want to count the iteration of cases OK and NotOK and overall cases inside xslt file.
How I cold do so? If I want to know the sum of both iteration how could I write it?
my For loops are as:
<xsl:for-each select="test">
<xsl:variable name="LinkName" select="attribute::name"/>
<tr>
<th style="text-align:left;vertical-align:top;position:"><a name="{$LinkName}"><xsl:value-of select="$LinkName"/></a></th>
<xsl:for-each select="descendant::node()">
<xsl:choose>
<xsl:when test="attribute::state='NotOK'">
<tr>
<td bgcolor="red"><xsl:value-of select="description"/></td>
</tr>
</xsl:when>
<xsl:when test="attribute::state='OK'">
<tr>
<td bgcolor="lime"><xsl:value-of select="description"/></td>
</tr>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</tr>
</xsl:for-each>
Update:
<table>
<tr bgcolor="coral">
<th>Test cases</th>
<th>Info</th>
</tr>
<xsl:for-each select="test">
<xsl:variable name="Summation"/>
<xsl:variable name="LinkIt" select="#name"/>
<xsl:choose>
<xsl:when test="descendant::node()/#state='NotOK'">
<tr>
<td bgcolor="red"><xsl:value-of select="$LinkIt"/></td>
<td>
<xsl:value-of select="count(descendant::node()[#state='NotOK'])"/> of <xsl:value-of select="count(descendant::node()[#state='OK']) + count(descendant::node()[#state='NotOK'])"/>
</td>
</tr>
</xsl:when>
<xsl:when test="descendant::node()/attribute::state='OK'">
<tr>
<td bgcolor="lime"><xsl:value-of select="$LinkIt"/></td>
<td>
---
</td>
</tr>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</table>
for-each is not a loop. If you want to count all descendant nodes of the test elements then simply use <xsl:value-of select="count(test/descendant::node())"/>. You can also add predicates to XPath expressions, like count(test/descendant::node()[attribute::state='NotOK']).
Inside of a <xsl:for-each select="test"> the context node is a test element so any count expression should be relative to that e.g. count(descendant::node()[attribute::state='NotOK']).
I use xslt to extract information form a xml file.
the xml file is :
<object>
<identifier>identifier</identifier>
<link>UD</link>
<title>Current Title</tite>
<impact>
<product>The product</product>
<evolution id="Evo 1">
<descr>Current description</descr>
</evolution>
</impact>
</object>
my xlst file is :
<xsl:for-each select="//object">
<tr>
<td>
<xsl:value-of select="identifier"/>
</td>
<td>
<xsl:value-of select="link"/>
</td>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="impact[1]/product"/>
</td>
<td>
<xsl:value-of select="impact[1]/product/evolution[1]/#id"/>
</td>
<td>
<xsl:value-of select="impact[1]/product/evolution[1]/descr"/>
</td>
</tr>
However, I can't seem to get the last two xsl values, I must have made a mistake (the first 4 columns are OK). Could you explain me why ?
Evolution is a sibling, not a child of product - it is a direct child of impact.
<xsl:value-of select="impact[1]/evolution[1]/#id"/>
<xsl:value-of select="impact[1]/evolution[1]/descr"/>
I want to Remove the zeros or any other values after point(eg 12.000000000000).
I am using xslt code .my code is like
<xsl:if test="value!= ''">
<tr>
<td>
value
</td>
<td>
<xsl:value-of select="value"/>
</td>
</tr>
</xsl:if>
how can I achive this?
Use Number formatting as:
<xsl:if test="value!= ''">
<tr>
<td>
value
</td>
<td>
<xsl:value-of select="format-number(value,'0')"/>
</td>
</tr>
</xsl:if>
You can use the format-number function:
<xsl:value-of select="format-number(value,'#')"/>
Refer to:
http://www.w3.org/TR/xslt/#format-number
Just use:
substring-before(concat(value, '.'), '.')
This works for any value -- not just a number. The result is correct even if value doesn't contain any dot character.
I have a custom DataViewWebPart to which I would like to add paging. I have included the meat of the XSLT I am using to form the scope of the details for my web part below. Any suggestions on how to implement paging on this item (since I am utilizing keys it's not so clear to me).
<xsl:key name="casebystate" match="Row" use="#StoreState"/>
<xsl:template match="/">
<xsl:variable name="cbs_Rows" select="/dsQueryResponse/Rows/Row/#StoreState"/>
<table border="0" width="100%" cellpadding="2" cellspacing="0">
<tr valign="top">
<th class="ms-vh" nowrap="nowrap">State</th>
<th class="ms-vh" nowrap="nowrap">Totals</th>
</tr>
<xsl:for-each select="//Row[generate-id() = generate-id(key('casebystate', #StoreState)[1])]">
<xsl:sort select="#StoreState"/>
<xsl:for-each select="key('casebystate', #StoreState)">
<xsl:call-template name="CaseByState.rowview" />
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="CaseByState.rowview">
<xsl:variable name="cbs_NewSortValue" select="ddwrt:NameChanged(string(#StoreState), 0)"/>
<xsl:if test="string-length($cbs_NewSortValue) > 0">
<tr id="group0{generate-id()}">
<td class="abh-chrtStatTitle">
<xsl:value-of select="#StoreState"/>
</td>
<td class="abh-chrtStatValue">
<xsl:value-of select="count(key('casebystate', #StoreState))"></xsl:value-of>
</td>
</tr>
</xsl:if>
</xsl:template>
Thanks for the help in advance!
If you are using Sharepoint Designer 2010, are you able to select your dvwp in the designer, go to the data view tools section and click on paging from the options tab of the ribbon? That should allow you to specify paging for your webpart.
I have such xml:
<A1>
<B1>
<C1>
<C2>
<C3>
</B1>
<B2>
<C4>
<C5>
<C6>
</B2>
</A1>
<A2>
<B3>
<C7>
<C8>
<C9>
</B3>
<B4>
<C10>
<C11>
<C12>
</B4>
</A2>
I need to transform it to table with nested rows:
<table border="yes">
<tr>
<td>A1</td>
<td>B1</td>
<td>C1</td>
</tr>
<tr>
<td></td>
<td></td>
<td>C2</td>
</tr>
<tr>
<td></td>
<td></td>
<td>C3</td>
</tr>
<tr>
<td></td>
<td>B2</td>
<td>C3</td>
</tr>
<tr>
<td></td>
<td></td>
<td>C4</td>
</tr>
A and B appear only if they are new (not repeating in every row);
I'm trying to use position()
<xsl:template match="c">
<tr>
<td>
<xsl:if test="IT IS THE FIRST C IN A">
<xsl:value-of select="ancestor::A"/>
</xsl:if>
</td>
<td>
<xsl:if test="position(1)">
<xsl:value-of select="parent"/>
</xsl:if>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
It seems that we should emulate position() for ancestor.
Is there a general solution for any number of nested rows?
You perhaps need something like the following (if I understood your question correctly):
<xsl:template match="C">
<tr>
<td>
<xsl:if test="generate-id(ancestor::A/descendant::C[1]) = generate-id(.)">
<xsl:value-of select="ancestor::A"/>
</xsl:if>
</td>
<td>
<xsl:if test="not(previous-sibling::C)">
<xsl:value-of select=".."/>
</xsl:if>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="descendant::C"/>
</xsl:template>
Edit: you may also use
not(previous-sibling::C) and not(../previous-sibling::B)
as the first test (instead of using generate-id()).