Текущее выбранное решение :
//comment()/following-sibling::*[1]/self::item
не работает в случае, когда между комментарием и элементом есть инструкция обработки (или целая группа инструкций обработки) - как это было отмечено в комментарии Мартина Хоннена. *
Приведенное ниже решение не имеет такой проблемы .
Следующее выражение XPath выбирает только узлы элементов, которым непосредственно предшествует узел комментария, или непосредственно предшествует текстовый узел только для пробелов, которому непосредственно предшествует узел комментария:
(//comment()
/following-sibling::node()
[1]
[self::text()
and
not(normalize-space())
]
/following-sibling::node()
[1] [self::item]
)
|
(//comment()
/following-sibling::node()
[1]
[self::item]
)
Вот полный тест :
Мы используем этот XML-документ:
<root>
<list>
<!-- foo's comment -->
<item name="foo" />
<item name="bar" />
<!-- another foo's comment -->
<item name="another foo" />
<!-- comment 3 --><item name="immed.after 3"/>
<!-- comment 4 --><?PI ?><item name="after PI"/>
</list>
</root>
Когда к указанному XML-документу применено следующее преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"
(//comment()
/following-sibling::node()
[1]
[self::text()
and
not(normalize-space())
]
/following-sibling::node()
[1] [self::item]
)
|
(//comment()
/following-sibling::node()
[1]
[self::item]
)
"/>
</xsl:template>
</xsl:stylesheet>
желаемый, правильный результат выдается :
<item name="foo"/>
<item name="another foo"/>
<item name="immed.after 3"/>