我有一个XML文件,当在节级别=“ 1”中嵌套节级别=“ 2”时也遇到了问题,并且还希望以下兄弟参数应进入节级别1,但我无法获取它。 / p>
输入XML
<section level="1" counter="yes">
<section level="2" counter="yes">
<title>Introduction</title>
</section>
<para>Started the campaign with reviewing the top procedures for men.</para>
<para>Gynecomastia (removal of breast tissue).</para>
<section level="2" counter="yes">
<title>Capturing the Wave</title>
</section>
<para>Our focus initially was to create robust website content.</para>
<para>Started the campaign with reviewing the top procedures for men.</para>
<section level="3" counter="yes">
<title>Our Approach: Build the Platform</title>
</section>
<para>Our criteria included that each service and landing page included at least 600 words</para>
<para>Our focus initially was to create robust website content.</para>
<section level="4" counter="yes">
<title>Capturing the Wave</title>
</section>
<para>Our content-first strategy, along with a mobile-responsive design</para>
<para>Our focus initially was to create robust website content.</para>
</section>
输出XML:-
<section level="1" counter="yes">
<section level="2" counter="yes">
<title>Introduction</title>
<para>Started the campaign with reviewing the top procedures for men.</para>
<para>Gynecomastia (removal of breast tissue).</para>
</section>
<section level="2" counter="yes">
<title>Capturing the Wave</title>
<para>Our focus initially was to create robust website content.</para>
<para>Started the campaign with reviewing the top procedures for men.</para>
<section level="3" counter="yes">
<title>Our Approach: Build the Platform</title>
<para>Our criteria included that each service and landing page included at least 600 words</para>
<para>Our focus initially was to create robust website content.</para>
<section level="4" counter="yes">
<title>Capturing the Wave</title>
<para>Our content-first strategy, along with a mobile-responsive design</para>
<para>Our focus initially was to create robust website content.</para>
</section>
</section>
</section>
</section>
和xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section[@level = '2']">
<xsl:element name="section">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::*"/>
<xsl:variable name="prev-level-value" select="."/>
<xsl:for-each select="following-sibling::*:section[@level = '3']">
<xsl:variable name="curr-level" select="@level - 1"/>
<xsl:variable name="curr-level-value" select="preceding-sibling::*:section[@level = $curr-level][1]"/>
<xsl:apply-templates select="self::*:section[@level = '3'][$curr-level-value = $prev-level-value]" mode="nested"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="section[@level = '3']" mode="nested">
<xsl:element name="section">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::*"/>
<xsl:variable name="prev-level-value" select="."/>
<xsl:for-each select="following-sibling::*:section[@level = '4']">
<xsl:variable name="curr-level" select="@level - 1"/>
<xsl:variable name="curr-level-value" select="preceding-sibling::*:section[@level = $curr-level][1]"/>
<xsl:apply-templates select="self::*:section[@level = '4'][$curr-level-value = $prev-level-value]" mode="nested"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="section[@level = '4']" mode="nested">
<xsl:element name="section">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::*"/>
<xsl:variable name="prev-level-value" select="."/>
<xsl:for-each select="following-sibling::*:section[@level = '5']">
<xsl:variable name="curr-level" select="@level - 1"/>
<xsl:variable name="curr-level-value" select="preceding-sibling::*:section[@level = $curr-level][1]"/>
<xsl:apply-templates select="self::*:section[@level = '5'][$curr-level-value = $prev-level-value]" mode="nested"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="section[@level = '5']" mode="nested">
<xsl:element name="section">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::*"/>
<xsl:variable name="prev-level-value" select="."/>
<xsl:for-each select="following-sibling::*:section[@level = '6']">
<xsl:variable name="curr-level" select="@level - 1"/>
<xsl:variable name="curr-level-value" select="preceding-sibling::*:section[@level = $curr-level][1]"/>
<xsl:apply-templates select="self::*:section[@level = '6'][$curr-level-value = $prev-level-value]" mode="nested"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="section[@level = '6']" mode="nested">
<xsl:element name="section">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::*"/>
<xsl:variable name="prev-level-value" select="."/>
<xsl:for-each select="following-sibling::*:section[@level = '7']">
<xsl:variable name="curr-level" select="@level - 1"/>
<xsl:variable name="curr-level-value" select="preceding-sibling::*:section[@level = $curr-level][1]"/>
<xsl:apply-templates select="self::*:section[@level = '7'][$curr-level-value = $prev-level-value]" mode="nested"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我已经在输入xml中运行XSLT,那么我的输出是:
<section level="1" counter="yes">
<section level="2" counter="yes">
<title>Introduction</title>
</section>
<para>Started the campaign with reviewing the top procedures for men.</para>
<para>Gynecomastia (removal of breast tissue).</para>
<section level="2" counter="yes">
<title>Capturing the Wave</title>
<section level="3" counter="yes">
<title>Our Approach: Build the Platform</title>
<section level="4" counter="yes">
<title>Capturing the Wave</title>
</section>
</section>
</section>
<para>Our focus initially was to create robust website content.</para>
<para>Started the campaign with reviewing the top procedures for men.</para>
<section level="3" counter="yes">
<title>Our Approach: Build the Platform</title>
</section>
<para>Our criteria included that each service and landing page included at least 600 words</para>
<para>Our focus initially was to create robust website content.</para>
<section level="4" counter="yes">
<title>Capturing the Wave</title>
</section>
<para>Our content-first strategy, along with a mobile-responsive design</para>
<para>Our focus initially was to create robust website content.</para>
</section>
答案 0 :(得分:1)
考虑使用xsl:for-each-group group-starting-with
并编写一个处理级别嵌套的递归函数:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$nodes" group-starting-with="section[@level = $level]">
<xsl:choose>
<xsl:when test="self::section[@level = $level]">
<xsl:copy>
<xsl:apply-templates select="@*, *"/>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="section[@level = 1 and @level < section/@level]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:sequence select="mf:group(*, 2)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94rmq5W
该示例是XSLT 3(自2017年以来由Saxon 9.8或更高版本以及Altova 2017或更高版本支持),但是对于XSLT 2处理器,当然可以拼写使用的xsl:mode
声明:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$nodes" group-starting-with="section[@level = $level]">
<xsl:choose>
<xsl:when test="self::section[@level = $level]">
<xsl:copy>
<xsl:apply-templates select="@*, *"/>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="section[@level = 1 and @level < section/@level]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:sequence select="mf:group(*, 2)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>