XPath для значений атрибутов colspan, как их понимает браузер?

У меня есть таблица HTML, в которой, возможно, отсутствуют или неправильно сформированы значения colspan:

<table border = "1">
  <tbody>
    <tr>
      <th>A</th> <th>B</th> <th>C</th> <th>D</th>
      <th>E</th> <th>F</th> <th>G</th> <th>H</th>
      <th>I</th> <th>J</th> <th>K</th> <th>L</th>
      <th>M</th> <th>N</th> <th>O</th> <th>P</th>
      <th>Q</th> <th>R</th> <th>S</th> <th>T</th>
      <th>U</th> <th>V</th> <th>W</th> <th>Y</th>
    </tr>
    <tr>
      <td                         >  0 </td>
      <td colspan = ""              >  1 </td>
      <td colspan = "0"             >  2 </td>
      <td colspan = "2"             >  3 </td>
      <td colspan = "-2"            >  4 </td>
      <td colspan = "+ 2"           >  5 </td>
      <td colspan = "+2"            >  6 </td>
      <td colspan = "*2#%@!"        >  7 </td>
      <td colspan = "2.7"           >  8 </td>
      <td colspan = "-2.3"          >  9 </td>
      <td colspan = "2e1"           > 10 </td>
      <td colspan = " 2 "           > 11 </td>
      <td colspan = "2xx"           > 12 </td>
      <td colspan = "2 3"           > 13 </td>
      <td colspan = "2" colspan = "3" > 14 </td>
    </tr>
  </tbody>
</table>

Я хотел бы получить значение colspan каждого td, поскольку браузер HTML5 «понял» бы их. В настоящее время я пытаюсь выяснить, что говорит об этом спецификация W3C, но давайте учтем, что результаты, отображаемые при запуске приведенного выше фрагмента, являются моим ожидаемым результатом:

colspan Значение HTML5 отсутствующий 1""1"0"1"2"2"-2"1"+ 2"1"+2"2"*2#%@!"1"2.7"2"-2.3"1"2e1"2" 2 "2"2xx"2"2 3"2"2" и "3"2

Как я могу добиться этого с помощью XPath 3.1?


Я попробовал это выражение XPath:

//td/( (1, @colspan[. castable as xs:double]) => max() => xs:integer() )

Но у него есть несколько проблем, например, преобразование "2e1" в 20 вместо 2.

Рассмотрим сопоставление шаблонов регулярных выражений для нормализованного по пространству значения для извлечения начальных целочисленных символов, игнорируя все символы, начинающиеся с первого нецелого символа. Тогда успешное совпадение дает ведущее целое число; все остальное дает 1.

kjhughes 18.06.2024 17:27
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
2
1
132
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Рассмотрим шаблон регулярного выражения, соответствующий значению, для извлечения символов начальных цифр, игнорируя все символы, начинающиеся с первого нецифрового символа. Тогда успешное совпадение дает ведущее целое число; все остальное дает 1:

//td/(if (matches(@colspan[1],'^\s*\+?[1-9]\d*')) 
          then replace(@colspan[1], '^\s*\+?(\d+).*$', '$1') 
          else '1')

Обновление: теперь обрабатывается обновление вопросов, в которое добавлены случаи colspan = "0" и colspan = "+2".

Обновление 2: добавлен [1] в @colspan согласно наблюдению Фравадоны о том, что (неправильно сформированные) HTML-таблицы могут иметь несколько атрибутов @colspan.

@Fravadona: Безумно, что вы встретите два атрибута @colspan в одном элементе, но реальный мир может быть беспорядочным. Обновлено.

kjhughes 21.06.2024 15:00

Согласно стандартам W3C и WHATWG, допустимое значение colspan в терминах регулярного выражения имеет форму ^\s*\+?(\d+).*, при этом часть в круглых скобках является частью, которую необходимо преобразовать в десятичное число. Оба стандарта возвращаются к 1, когда colspan равен нулю, недействителен или отсутствует.

Ответ @kjhughes работает достаточно хорошо, но есть другой способ с analyze-string и max:

//td/( max((1, analyze-string(@colspan[1], "^\s*\+?\d+")/fn:match)) )

В СТОРОНЕ

Вот некоторые важные моменты стандарта W3C:

  1. Если текущая ячейка имеет атрибут colspan, то проанализируйте значение этого атрибута и пусть colspan будет результатом.

    Если синтаксический анализ этого значения не удался, или вернул ноль, или если атрибут отсутствует, то вместо этого пусть colspan будет 1.

  1. Пропускайте пробелы.
  1. Если символ, указанный в позиции, представляет собой символ U+002B ПЛЮС ЗНАК (+), перейдите к следующему символу. (Знак «+» игнорируется, но это не соответствует.)
  1. Соберите последовательность символов в диапазоне от U+0030 ЦИФРА НОЛЬ (0) до U+0039 ЦИФРА ДЕВЯТЬ (9) и интерпретируйте полученную последовательность как целое число с основанием десять. Пусть значение будет этим целым числом.

Пока позиция не указывает за конец ввода, а символ в позиции является одним из символов, добавьте этот символ в конец результата и переместите позицию на следующий символ во вводе.

Красиво и лаконично! И в целом отличная работа с вопросами/ответами. 👍

kjhughes 19.06.2024 14:23

Другие вопросы по теме