Какой XSLT позволяет мне пропускать теги <li>, содержащие теги <a> с определенными значениями href?

Это продолжение моего предыдущего вопроса.

Я не могу разобраться с XSLT, чтобы сделать следующее. У меня есть HTML-код с одним или несколькими тегами <ul>. Теги <li> могут содержать теги <a>. Я хочу удалить любой тег <li>, если он содержит привязку, в которой href соответствует определенному шаблону.

Пример:

<ul>
  <li><a href = "/some/old/path">One</a></li>
  <li><a href = "/other/old/path">Two</a></li>
  <li><a href = "/some/older/path">Three</a></li>
  <li><a href = "/other/older/path">Four</a></li>
</ul>

Я хочу удалить строки <li>, в которых href содержит older, чтобы результат был таким:

<ul>
  <li><a href = "/some/old/path">One</a></li>
  <li><a href = "/other/old/path">Two</a></li>
</ul>

Строки, которые я хочу удалить, могут быть в любом порядке и разбросаны по нескольким тегам <ul>. Я в порядке, если в итоге у меня останется пустая пара <ul></ul> (но бонусные баллы, если такой полученный пустой список можно легко удалить). <li> теги, не содержащие привязки или содержащие несовпадающую привязку, следует оставить как есть.

Я приблизился к следующему:

<xsl:template match = "li/a[contains(@href, 'older')]">
</xsl:template>

но остается открытие <li>:

<ul>
  <li><a href = "/some/old/path">One</a></li>
  <li><a href = "/other/old/path">Two</a></li>
  <li>
  <li>
</ul>

Как мне избавиться от всей строки <li>?

Вот полный HTML-код, с которым я работаю:

<html>
<head>
<!-- lots of stuff I don't care about -->
</head>
<body>
<div>
  <!-- lots of stuff I don't care about -->
  <div>
     <!-- lots of stuff I don't care about -->
     <div id = "key_div">
         <div id = "ignore_this">
           <!-- lots of stuff I don't care about -->
         </div>
         <p>More junk I don't want</p>
         <p>Even more junk I don't want</p>
         <h2><span class = "someClass" id = "someID">Header</span></h2>
         <p>Stuff I want to keep</p>
         <!-- A lot of stuff I want to keep -->
         <p>More stuff I want to keep</p>
         <ul>
           <li><a href = "/some/old/path">One</a></li>
           <li><a href = "/some/old/other">Two</a></li>
           <li><a href = "/some/older/path">Three</a></li>
           <li><a href = "/some/older/other">Four</a></li>
         </ul>
         <ul>
           <li>Leave this as-is</li>
         </ul>
     </div>
     <!-- lots of stuff I don't care about -->
  </div>
  <!-- lots of stuff I don't care about -->
</div>
</body>
</html>

А вот XSLT:

<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
    <xsl:output method = "html" indent = "yes" encoding = "utf-8"/>

    <xsl:template match = "/html">
        <html>
            <head>
                <title></title>
            </head>
            <body>
                <xsl:apply-templates select = "//div[@id='key_div']/h2"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match = "h2">
        <h1>
            <xsl:value-of select = "." />
        </h1>
        <xsl:apply-templates select = "following-sibling::*"/>
    </xsl:template>

    <!-- My failed attempt to remove certain li lines -->
    <xsl:template match = "li/a[contains(@href, 'older')]">
    </xsl:template>

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

Мой текущий результат:

<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8">
<title></title>
</head>
<body>
<h1>Header</h1>
<p>Stuff I want to keep</p>
<p>More stuff I want to keep</p>
<ul>
           <li><a href = "/some/old/path">One</a></li>
           <li><a href = "/some/old/other">Two</a></li>
           <li>
           <li>
         </ul>
<ul>
           <li>Leave this as-is</li>
         </ul>
</body>
</html>

Мне просто нужно придумать, как удалить полную строку <li> для соответствующих hrefs.

Улучшение производительности загрузки с помощью 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 страниц, которые помогут...
0
0
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

С:

match = "li/a[contains(@href, 'older')]"

вы выбираете элемент a.

Попробуйте изменить его на:

match = "li[contains(a/@href, 'older')]"

(Непроверено, и, честно говоря, я даже не просматривал ваш полный XSLT.)

Ответ @DanielHaley сработал для конкретного примера, который я опубликовал. Оказывается, мои реальные потребности были немного сложнее, и его ответ привел к тому, что при обновлении условия было отфильтровано больше тегов <li>, чем ожидалось.

В моем немного более сложном случае я могу использовать такие привязки, как:

<ul>
  <li><a href = "/some/path/old">One</a></li>
  <li><a href = "/other/path/older">Two</a></li>
  <li><a href = "/different/path/young">Two</a></li>
</ul>

и я хочу сохранить только привязки «старые». И моя версия XSLT (macOS 14) не поддерживает функцию ends-with. Если бы это было так, я мог бы использовать:

match = "li[not(ends-with(a/@href, 'old'))]"

Из-за отсутствия ends-with мне нужно совпадение типа:

match = "li[not(contains(a/@href, 'old')) or contains(a/@href, 'older')]

Но это также отфильтровывает любой тег <li>, который не содержит привязки.

Следующее изменение сработало для моего полного случая:

<xsl:template match = "li[a[not(contains(@href, 'old')) or contains(@href, 'older')]]" />

Теперь это фильтрует только теги <li>, у которых есть тег <a> со значением href, которое не заканчивается на "old".

Ваше выражение НЕ удалит <li><a href = "/any/older/path/old">xyz</a></li>, несмотря на то, что значение href заканчивается на «старый».

michael.hor257k 06.05.2024 06:15

@michael.hor257k Но цель состоит в том, чтобы оставить только те, которые заканчиваются на «старый». Поэтому я бы не хотел удалять ваш пример. Я думаю, вы имеете в виду, что мой ответ удалит этот пример, хотя на самом деле я бы этого не хотел. Возможно, но на самом деле это не тот случай, который мне нужно рассматривать в моем реальном случае использования. В любом случае, я, скорее всего, заменю свой обходной путь ends-with на ваш. Это проще и менее запутанно.

HangarRash 06.05.2024 06:19

моя версия XSLT (macOS 14) не поддерживает ends-with функция. Если бы это было так, я мог бы использовать:

match = "li[ends-with(a/@href, 'old')]"

Вот одна из возможных реализаций ends-with() в XSLT 1.0:

<xsl:template match = "li[contains(concat(a/@href, '&#133;'), 'old&#133;')]"/>

Ах, я подумал, что должен быть более умный обходной путь из-за отсутствия ends-with. Хорошо знать.

HangarRash 06.05.2024 06:15

Кстати, поскольку я хочу сохранить только узлы <li> с «href», оканчивающимся на «old», для этого нужен not( ) вокруг contains( ). Я пропустил not в своем ответе. Зафиксированный.

HangarRash 06.05.2024 06:27

Я сформулировал свой ответ (а также комментарий к вашему вопросу) в свете отрывка, процитированного из вашего ответа (который вы теперь изменили). Я надеюсь, что вы будете знать, как внести необходимые коррективы.

michael.hor257k 06.05.2024 06:31

P.S. Если вы используете процессор libxslt XSLT, входящий в состав macOS, включите тег xslt-1.0 во все вопросы по XSLT (рядом с тегом xslt). Тег libxslt также может быть полезен, так как этот процессор поддерживает большое количество функций расширения.

michael.hor257k 06.05.2024 06:36

Спасибо за предложение тега. У меня мало опыта работы с XSLT (очевидно), и я не учел, что существуют разные версии.

HangarRash 06.05.2024 06:39

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