PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : XSLT: xsl:for-each mit concat() und position()



paule
20-11-2020, 18:41
Hallo,

Ich versuche die Werte (Value1..3) eines Punktes in einer Tabelle anzuzeigen. Dazu gehe ich in der xsl:for-each Schleife alle Treffer zu "].Value1" durch und versuche mit concat() und position() die anderen Pfade zusammenzubauen. Wie man in Col2 sehen kann, wird der String durch concat() richtig zusammengebaut. Col3 zeigt aber, dass es nicht funktioniert oder ich das concat() falsch in den xPath einbaue.


No Value1 [m³] Value2 [°C] Value3 [%] Col1 Col2 Col3
1 640 20 40 Point[1].Value1 Point[1].Value2 640
2 641 20 40 Point[2].Value1 Point[2].Value2 640
3 642 20 40 Point[3].Value1 Point[3].Value2 640

Ich verstehe auch nicht, warum in Col3 3x 640 ausgegeben wird, obwohl ich Value2 referenziere. Wenn alles vor @value kaputt ist oder ignoriert wird, müsste er ja wie in der ersten Spalte den korrekten Value1 ausgeben.

Wie bekomme ich in jeder Zeile die entsprechenden Werte eines Punktes angezeigt? Mein Ziel ist folgende Ausgabe:


No Value1 [m³] Value2 [°C] Value3 [%]
1 640 20 40
2 641 21 41
3 642 22 42


Viele Grüße,
Paul




<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<head></head>
<body>
<table>
<tr>
<th>No</th>
<th>Value1 [m³]</th>
<th>Value2 [°C]</th>
<th>Value3 [%]</th>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>

<xsl:for-each select="//*[contains(@name, '].Value1')]">
<tr>
<td>
<xsl:value-of select="position()"/>
</td>
<td>
<xsl:value-of select="@value"/>
</td>
<td>
<xsl:value-of select="//item[@name='Point[1].Value2']/@value"/>
</td>
<td>
<xsl:value-of select="//item[@name='Point[1].Value3']/@value"/>
</td>

<td>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="concat('Point[', position(), '].Value2')"/>
</td>

<td>
<xsl:value-of select="//item[concat(@name='Point[', position(), '].Value2')]/@value"/>
</td>
</tr>
</xsl:for-each>

</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>




<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="report.xsl" ?>
<root>
<body>
<part>
<values>
<item name="Point[1].Value1" value="640" unit="m³" />
<item name="Point[1].Value2" value="20" unit="°C" />
<item name="Point[1].Value3" value="40" unit="%" />
<item name="Point[2].Value1" value="641" unit="m³" />
<item name="Point[2].Value2" value="21" unit="°C" />
<item name="Point[2].Value3" value="41" unit="%" />
<item name="Point[3].Value1" value="642" unit="m³" />
<item name="Point[3].Value2" value="22" unit="°C" />
<item name="Point[3].Value3" value="42" unit="%" />
</values>
</part>
</body>
</root>

paule
21-11-2020, 23:30
Crosspost auf Stackoverflow (https://stackoverflow.com/questions/64949104/how-to-build-a-xpath-with-concat-and-position-in-a-xslfor-each)

paule
22-11-2020, 01:44
Mit Hilfe eines Kommentars auf Stackoverflow habe ich folgende Lösung gefunden:



<xsl:for-each select="//item[position() mod 3 = 0 and contains(@name, 'Point')]">
<tr>
<td>
<xsl:value-of select="position()"/>
</td>
<td>
<xsl:value-of select="format-number(@value, '0.00')"/>
</td>
<td>
<xsl:value-of select="following-sibling::item[contains(@name, 'Value2')]/@value"/>
</td>
<td>
<xsl:value-of select="following-sibling::item[contains(@name, 'Value3')]/@value"/>
</td>
<td>
<xsl:value-of select="@name"/>
</td>
</tr>
</xsl:for-each>

Als kleiner Schönheitsfleck bleibt noch die Konstante für die Modulo-Operation, die angepasst werden muss, wenn sich die Anzahl values pro Punkt ändert.

Grüße,
Paul