#xslt #xslt-2.0
#xslt #xslt-2.0
Вопрос:
Если следующий li
элемент-элемент-брат p
, то как переместить li
элемент?
Ввод
<root>
<p>start</p>
<p>aaaaa</p>
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
<p>aaaaa</p>
<p>aaaaaa</p>
** Ожидаемый результат**
<root>
<p>start</p>
<p>aaaaa
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</p>
<p>aaaaa</p>
<p>aaaaaa</p>
XSLT:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
<xsl:if test="following-sibling::*[1][self::li]">
<xsl:for-each select="following-sibling::*[1][self::li]">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</xsl:if>
</p>
</xsl:template>
Комментарии:
1. Почему в вашем шаблоне создан узел «al»? Я не вижу ни одного узла «al» в вашем требуемом выводе.
2. @Себастьян, я отредактировал свой вопрос, пожалуйста, проверьте
Ответ №1:
Поскольку вы можете использовать XSLT-2.0, вы можете использовать xsl:for-each-group
. Итак, ниже приведен один из способов достижения желаемого результата:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="p[name(following-sibling::*[1]) = 'li']">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:for-each-group select="following-sibling::*" group-adjacent="name()">
<xsl:if test="position()=1">
<xsl:copy-of select="current-group()" />
</xsl:if>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="li[preceding-sibling::*[1] = (preceding-sibling::p[1] | preceding-sibling::li[1])]" />
</xsl:stylesheet>
Вывод:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p>start</p>
<p>aaaaa<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</p>
<p>aaaaa</p>
<p>aaaaaa</p>
</root>
Комментарии:
1. Сэр, @zx485 Спасибо за ответ. Можете ли вы проверить последние 2 залога, если элемент li не предшествует элементу-родственному элементу p, тогда не удаляйте элемент li ( xsltfiddle. liberty-development.net/nb9NXUL/2 ).
2. Спасибо, сэр, дайте мне решение!
Ответ №2:
Похоже, вы просто хотите
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="p">
<xsl:copy>
<xsl:apply-templates select="node(), tail(current-group())"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
https://xsltfiddle .liberty-development.net/pNvt6XN
tail
Функция не будет поддерживаться процессором XSLT 2, но, конечно current-group()[position() gt 1]
, может быть использована вместо этого.
Комментарии:
1. Сэр, пожалуйста, проверьте последнюю строку, если отредактируйте мое изменение последнего элемента ввода, тогда не следует переходить к предыдущему элементу. ( xsltfiddle. liberty-development.net/pNvt6XN/1 )
2. @Sam, подумайте о том, чтобы отредактировать свой вопрос с учетом имеющихся у вас входных данных и желаемых выходных данных.
Ответ №3:
Вот способ, которым вы могли бы это сделать, который также работал бы в XSLT 1.0.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<!-- P node that has a li node directly below it -->
<xsl:template match="p[following-sibling::*[1][self::li]]">
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:copy>
<xsl:value-of select="."/>
<!-- Copy all li nodes that share the same p as their preceding-sibling -->
<xsl:copy-of select="following-sibling::li[generate-id(preceding-sibling::p[1]) = $id]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="li"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Посмотрите, как это работает здесь: https://xsltfiddle .liberty-development.net/nb9NXUL/3
Комментарии:
1. Спасибо за ответ. Можете ли вы проверить последние 2 залога, если элемент li не предшествует элементу-родственному элементу p, тогда не удаляйте элемент li ( xsltfiddle. liberty-development.net/nb9NXUL/1 ).