Скажем, у меня есть:
<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.
Очевидно, я могу разобрать это в какой-то ассоциативный массив, а затем вернуться назад. Есть идеи, как я могу это сделать с помощью простой обработки текста (замена строк, регулярное выражение и т. д.)?
Спасибо!





Я предлагаю вам разобрать его в 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');
чем полагаться на реальную структуру.