Выделите родителей в строке xml

Скажем, у меня есть:

<ul>
    <li id = "x">
        <a href = "x">x</a>
    </li>

    <li id = "y">
        <a href = "y">y</a>

        <ul>
            <li id = "z">
                <a href = "z">z</a>
            </li>
        </ul>
    </li>
</ul>

Я хочу добавить значение класса ко всем элементам списка, которые являются родительскими для z. Итак, я хочу изменить y, но не x.

Очевидно, я могу разобрать это в какой-то ассоциативный массив, а затем вернуться назад. Есть идеи, как я могу это сделать с помощью простой обработки текста (замена строк, регулярное выражение и т. д.)?

Спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
229
8

Ответы 8

Я предлагаю вам разобрать его в DOM и вернуться назад, как вы думали. Регулярные выражения не очень хорошо работают для вложенных структур с произвольными уровнями вложенности.

Я бы использовал XSLT. Вы можете указать поиск узлов, которые являются предками z.

xpath имеет ось предков, которая включает всех предков текущего узла контекста.

// * [@ id = "z"] / предок :: li

* любой элемент [@ id = "z"], имеющий атрибут я бы со значением z (поскольку атрибут id, может (/ должен быть) только один такой элемент)
/ предок :: li все элементы Ли, которые являются предками этого

см. также: https://www.w3schools.com/xml/xpath_axes.asp

Атрибут будет добавлен только к элементам с дочерним элементом z.

Спасибо за вклад. Я подумал, что это невозможно без синтаксического анализа (или использования xsl и т. д.) ... Да ладно.

Пример всего XSLT:

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0">

  <xsl:variable name = "ancestors" select = "descendant::li[@id = 'z']/ancestor::li"/>

  <xsl:template match = "li">
    <xsl:copy>
      <!-- test if current li is in the $ancestors node-list -->
      <xsl:if test = "count($ancestors | .) = count($ancestors)">
        <xsl:attribute name = "class">ancestor</xsl:attribute>
      </xsl:if>
      <xsl:apply-templates select = "node() | @*"/>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

Это хорошо подходит для jQuery, если он вам доступен.

$("#z").parent().parent().addClass("foo");

В дополнение к ответу Джона Шихана:
С JQuery я бы предпочел использовать
$('#z').parents('li').addClass('myClass');
чем полагаться на реальную структуру.

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