Как выбрать столбец столбца по имени заголовка столбца с помощью xpath

У меня есть таблица результатов, и она выглядит следующим образом:

<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Type</th>
      <th>Amount</th>
      <th>Price</th>
      <th>Name</th>
      <th>Expiration</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>123</td>
      <td>Paper</td>
      <td>10 pcs.</td>
      <td>$10</td>
      <td>Premium Copier paper</td>
      <td>None</td>
    </tr>
    <tr>
      <td>321</td>
      <td>Paper</td>
      <td>20 pcs.</td>
      <td>$20</td>
      <td>Extra Copier paper</td>
      <td>None</td>
    </tr>
  </tbody>

И я хочу выбрать весь столбец по имени с помощью xpath, например. Я хочу, чтобы возвращаемый результат был массивом {<td>$10</td>, <td>$20</td>}, если его выбрали по названию столбца "Цена". Я новичок в xpath и не совсем уверен, как это сделать, но я уверен, что это возможно.

Ответ 1

Хорошо, я нашел ответ, который был бы достаточным и выглядел бы довольно элегантно. Здесь идет требуемая строка XPath:

//table/tbody/tr/td[count(//table/thead/tr/th[.="$columnName"]/preceding-sibling::th)+1]

Поместите имя столбца вместо $columnName. Это хорошо работает для меня. Там нет XSL или ничего, только чистая строка xpath. Как применить его - это еще один вопрос.

Ответ 2

Если вы нашли решение, я предлагаю опубликовать его в качестве ответа здесь, но просто для удовольствия, вот как я подхожу к этому:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:key name="kCol" match="td" use="count(. | preceding-sibling::td)"/>
  <xsl:param name="column" select="'Price'" />

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <found>
      <xsl:apply-templates select="table/thead/tr/th" />
    </found>
  </xsl:template>

  <xsl:template match="th">
    <xsl:if test=". = $column">
      <xsl:apply-templates select="key('kCol', position())" />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

При запуске с "Price" в качестве значения параметра:

<found>
  <td>$10</td>
  <td>$20</td>
</found>

При запуске с именем "Имя" в качестве значения параметра:

<found>
  <td>Premium Copier paper</td>
  <td>Extra Copier paper</td>
</found>

Ответ 3

Вы можете использовать этот XPath:

/table/tbody/tr/td[count(preceding-sibling::td)+1 = count(ancestor::table/thead/tr/th[.='Price']/preceding-sibling::th)+1]

Я бы подумал, что тестирование позиции (position()) td относительно позиции соответствующего th будет работать, но, похоже, не было, когда я тестировал.