#xml #xslt #xslt-1.0
#xml #xslt #xslt-1.0
Вопрос:
У меня есть это ниже xml
<root>
<s>
<name>self-1</name>
<parents>
<s>
<name>p-1-2</name>
<parents>
<s>
<name>p-1-2-1</name>
<parents>
<s>
<name>p-1-2-1-1</name>
</s>
</parents>
</s>
<s>
<name>p-1-2-2</name>
</s>
</parents>
</s>
</parents>
</s>
</root>
и мне нужно написать xslt1 для анализа этого xml, чтобы получить выходные данные, как показано ниже, цель состоит в том, чтобы сначала обработать все родительские узлы и, наконец, узел self-1. Пожалуйста, дайте мне несколько советов.
<ul>
<li>p-1-2-1-1</li>
<ul>
<li>p-1-2-1</li>
<li>p-1-2-2</li>
<ul>
<li>p-1-2</li>
<ul>
<!-- self -->
<li>self-1</li>
</ul>
</ul>
</ul>
</ul>
Ответ №1:
Вот мое предложение о том, как решить эту проблему:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="descendant::parents[not(s/parents)]"/>
</xsl:template>
<xsl:template match="parents | root">
<ul>
<xsl:apply-templates select="s/name"/>
<xsl:variable name="p" select="parent::s/parent::parents | parent::s/parent::root"/>
<xsl:if test="$p">
<li>
<xsl:apply-templates select="$p"/>
</li>
</xsl:if>
</ul>
</xsl:template>
<xsl:template match="name">
<li>
<xsl:value-of select="."/>
</li>
</xsl:template>
</xsl:stylesheet>
Это выводит
<ul>
<li>p-1-2-1-1</li>
<li>
<ul>
<li>p-1-2-1</li>
<li>p-1-2-2</li>
<li>
<ul>
<li>p-1-2</li>
<li>
<ul>
<li>self-1</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Это не совсем то, что вы просили, но это сделано намеренно: в вашем примере были ul
элементы с ul
дочерними элементами, но это не разрешено в HTML (http://www.w3.org/TR/html4/struct/lists.html#h-10.2 ). Таким образом, моя таблица стилей гарантирует, что результат является допустимым HTML, убедившись, что any ul
имеет только li
дочерние элементы.
Комментарии:
1. Большое спасибо, Мартин, я совершенно забыл, что могу использовать ось-потомок
Ответ №2:
для обработки нескольких узлов <s>
Я обновил шаблон <xsl:template match="parents | root">
примерно так, как показано ниже:
<xsl:template match="parents | root">
<ul>
<xsl:apply-templates select="s/name"/>
<xsl:choose>
<xsl:when test="parent::s/parent::parents">
<xsl:variable name="p" select="parent::s/parent::parents"/>
<li><xsl:apply-templates select="$p"/></li>
</xsl:when>
<xsl:when test="parent::s/parent::root">
<xsl:variable name="p" select="parent::s/parent::root"/>
<li><xsl:apply-templates select="$p"/></li>
</xsl:when>
</xsl:choose>
</ul>
</xsl:template>