我有多个主题,我需要包含section标签以及带有编号ID的主题元素
我的输入XML是:
<Article>
<Title>Mam</Title>
<Items>
<Item>
<Name>cyst1?</Name>
<Body>
<h1>aaa</h1><p>knee1.</p>
<h2>bbb</h2><p>knee2.</p>
</Body>
</Item>
<Item>
<Name>cyst2?</Name>
<Body>
<p>knee3.</p>
</Body>
</Item>
</Items>
XSL我用作:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="#all">
<xsl:template match="Article">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Title"/>
<xsl:template match="h1"/>
<xsl:template match="h2"/>
<xsl:template match="Items">
<xsl:for-each-group select="*" group-starting-with="Items">
<topic>
<xsl:attribute name="id">topic_Head<xsl:number count="Items | Item"/>
</xsl:attribute>
<title>
<xsl:value-of select="//Title"/>
</title>
<xsl:for-each-group select="current-group()" group-starting-with="Item">
<xsl:choose>
<xsl:when test="self::Item">
<topic>
<xsl:attribute name="id">topic_<xsl:number count="Items | Item"/>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</topic>
</xsl:when>
<xsl:otherwise>
<body>
<xsl:apply-templates select="current-group()"/>
</body>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</topic>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="Body">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="Name">
<title>
<xsl:apply-templates/>
</title>
</xsl:template>
输出我得到了:
<topic id="topic_1">
<title>Mam</title>
<topic id="topic_2">
<title>cyst1?</title>
<body>
<p>knee1.</p><p>knee2.</p>
</body>
</topic>
<topic id="topic_3">
<title>cyst2?</title>
<body>
<p>knee3.</p>
</body>
</topic>
预期产出:
<topic id="topic_1">
<title>Mam</title>
<topic id="topic_2">
<title>cyst1?</title>
<body>
<section id="section1">
<title>aaa</title><p>knee1.</p>
<section id="section2">
<title>bbb</title><p>knee2.</p>
</section>
</section>
</body>
</topic>
<topic id="topic_3">
<title>cyst2?</title>
<body>
<p>knee3.</p>
</body>
</topic>
我需要h1和h2作为具有Id属性的部分,并按照标题顺序关闭。
请建议我对此进行编码。提前谢谢。
答案 0 :(得分:0)
以下styleshhet会起作用。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ahf="http://www.antennahouse.com/names/XSLT/Functions/Document"
exclude-result-prefixes="#all">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Article">
<topic>
<xsl:attribute name="id" select="ahf:genTopicId(.)"/>
<xsl:apply-templates/>
</topic>
</xsl:template>
<xsl:template match="Title">
<title>
<xsl:apply-templates/>
</title>
</xsl:template>
<xsl:template match="Items">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Item">
<topic>
<xsl:attribute name="id" select="ahf:genTopicId(.)"/>
<xsl:apply-templates/>
</topic>
</xsl:template>
<xsl:template match="Name">
<title>
<xsl:apply-templates/>
</title>
</xsl:template>
<xsl:template match="Body">
<body>
<xsl:call-template name="groupBody">
<xsl:with-param name="prmBodyElem" select="*"/>
</xsl:call-template>
</body>
</xsl:template>
<xsl:template name="groupBody">
<xsl:param name="prmBodyElem" as="element()*"/>
<xsl:variable name="maxHn" as="xs:integer" select="ahf:getMaxHn($prmBodyElem)"/>
<xsl:choose>
<xsl:when test="$maxHn eq $notHn">
<xsl:apply-templates select="$prmBodyElem"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="$prmBodyElem" group-adjacent="ahf:genGroupNo(.,$maxHn,$prmBodyElem)">
<xsl:choose>
<xsl:when test="current-grouping-key() eq 0">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<section>
<xsl:attribute name="id" select="ahf:genSectionId(current-group()[1])"/>
<title>
<xsl:apply-templates select="./node()"/>
</title>
<xsl:call-template name="groupBody">
<xsl:with-param name="prmBodyElem" select="subsequence(current-group(),2)"/>
</xsl:call-template>
</section>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:variable name="notHn" as="xs:integer" select="9999"/>
<xsl:function name="ahf:getMaxHn" as="xs:integer">
<xsl:param name="prmElem" as="element()+"/>
<xsl:variable name="hn" as="xs:integer*">
<xsl:for-each select="$prmElem">
<xsl:choose>
<xsl:when test="matches(name(),'h[1-9]')">
<xsl:sequence select="xs:integer(substring(name(),2))"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$notHn"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="min($hn)"/>
</xsl:function>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<!-- Generate id number for topic -->
<xsl:function name="ahf:genTopicId" as="xs:string">
<xsl:param name="prmElem" as="element()"/>
<xsl:sequence select="concat('topic_',count($prmElem|root($prmElem)//*[self::Article or self::Item][. << $prmElem]))"/>
</xsl:function>
<!-- Grouping by hN (N = $prmMaxHn)
0: not h1, h2, h3...
> 1: hN group
-->
<xsl:function name="ahf:genGroupNo" as="xs:integer">
<xsl:param name="prmElem" as="element()"/>
<xsl:param name="prmMaxHn" as="xs:integer"/>
<xsl:param name="prmRange" as="element()*"/>
<xsl:variable name="GroupHn" as="xs:string" select="concat('h',$prmMaxHn)"/>
<xsl:sequence select="count($prmElem[self::*[name() eq $GroupHn]]) + count($prmElem/preceding-sibling::*[name() eq $GroupHn][(. is $prmRange[1]) or (. >> $prmRange[1])])"/>
</xsl:function>
<!--Generate id number for section -->
<xsl:function name="ahf:genSectionId" as="xs:string">
<xsl:param name="prmElem" as="element()"/>
<xsl:sequence select="concat('section_',count($prmElem|$prmElem/preceding::*[matches(name(),'h[1-9]')]))"/>
</xsl:function>
</xsl:stylesheet>
[结果]
<?xml version="1.0" encoding="UTF-8"?>
<topic id="topic_1">
<title>Mam</title>
<topic id="topic_2">
<title>cyst1?</title>
<body>
<section id="section_1">
<title>aaa</title>
<p>knee1.</p>
<section id="section_2">
<title>bbb</title>
<p>knee2.</p>
</section>
</section>
</body>
</topic>
<topic id="topic_3">
<title>cyst2?</title>
<body>
<p>knee3.</p>
</body>
</topic>
</topic>
我仍然担心如果预期结果是DITA主题实例,则不允许嵌套节元素。