Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath: Cant get the right value out of a selected Tag

Tags:

xslt

xpath

this is my first question here on stackoverflow, so please dont kill me. But lets get right to the problem. I have a given xhtml and need to get specific information out of it.

Here is my xsl file so far:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="http://www.w3.org/1999/xhtml">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"
        omit-xml-declaration="no" />
    <xsl:template match="html">
        <xsl:element name="Speisekarte">
            <xsl:attribute name="xsi:noNamespaceSchemaLocation"
                namespace="http://www.w3.org/2001/XMLSchema-instance">Speiseplan_Mensa_Schema.xsd</xsl:attribute>
            <xsl:for-each select=".//table[@class='table module-food-table']">
                <xsl:element name="Speisen">
                    <xsl:element name="namen">
                        <xsl:value-of select="./thead/tr/th[1]" />
                    </xsl:element>
                    <xsl:for-each select="./tbody/tr">
                        <xsl:element name="zutaten">
                            <xsl:value-of select="./td" />
                        </xsl:element>
                        <xsl:element name="preis">
                            <xsl:element name="Studenten">
                                <xsl:value-of select="./td[2]" />
                            </xsl:element>
                            <xsl:element name="Mitarbeiter">
                                <xsl:value-of select="./td[3]" />
                            </xsl:element>
                            <xsl:element name="Gäste">
                                <xsl:value-of select="./td[4]" />
                            </xsl:element>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

My problem is by the element "zutaten". I need to get "Hackbällchen in Rahmsauce" out of this xhtml file:

<tbody>
                  <tr>
                    <td style="width:70%">
                      Hackbällchen in <sup>(R)</sup> Rahmsauce <sup>(9,G,A,I)</sup>
                      <div class="price hidden-sm hidden-md hidden-lg">
                        <span>1,50&nbsp;&euro;</span><span>2,15&nbsp;&euro;</span><span>2,80&nbsp;&euro;</span>
                      </div>
                    </td>
                    <td class="hidden-xs" style="text-align:center">
                      1,50&nbsp;&euro;
                    </td>
                    <td class="hidden-xs" style="text-align:center">
                      2,15&nbsp;&euro;
                    </td>
                    <td class="hidden-xs" style="text-align:center">
                      2,80&nbsp;&euro;
                    </td>
                  </tr>
                </tbody>

I tried:

<xsl:value-of select="./td/text()" />

which give me this: Hackbällchen in Rahmsauce 1,50 2,15 € 2,80 € or i tried:

<xsl:value-of select="./td/text()[not(self::div)]" />

which give me an error.

And i tried many different things. Can u guys help me with this? Hope my english was good enough to understand my problem. Thanks in advance.

like image 516
Christopher Avatar asked Nov 24 '25 12:11

Christopher


2 Answers

The expression you want is this...

<xsl:value-of select="td[1]/text()" />

By doing td/text() (the ./ prefix is unnecessary here), you are getting all td nodes, and all the text underneath all these nodes.

like image 198
Tim C Avatar answered Nov 27 '25 23:11

Tim C


You are missing the predicate on the first column. The XPath ./td will select ALL of the td elements in that row. Using xsl:value-of will produce the computed text value of whatever you have selected, which happens to be all of the td elements (to include the text() node descendants). You can verify this by changing xsl:value-of to xsl:copy-of.

If you want just the text() from the first td column, use td[1]/text().

like image 38
Mads Hansen Avatar answered Nov 27 '25 21:11

Mads Hansen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!