如何获取具有不同输出类的普通段落作为部分级别标签



我需要具有不同类的普通para作为输出类名称ListN1-Nam和ListN3-Nam

我的源 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Body>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="ListN1-Nam"><b>A. Selvam-4, Item 1</b></p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="ListN3-Nam"><b>1. Selvam-4, Item 1</b></p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="ListN3-Nam"><b>2. Selvam-4, Item 1</b></p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="ListN1-Nam"><b>B. Selvam-4, Item 1</b></p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="BodyText_Center">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Body_Text">AAAA.</p>
<p outputclass="Normal"><b>Q:</b> Why?</p>
<p outputclass="Body_Text_Question"><b>Q:</b> What?</p>
<p outputclass="Body_Text_Answer"><b>A:</b> In.</p>
<p outputclass="Body_Text_Answer">The</p>
<p outputclass="Normal"><b>Q:</b> Why?</p>
<p outputclass="Body_Text_Question"><b>Q:</b> What?</p>
<p outputclass="Body_Text_Answer"><b>A:</b> In.</p>
<p outputclass="Body_Text_Answer">The</p>
</Body>

我的xslt我用于此部分级别格式:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="Body">
<xsl:copy>
<xsl:for-each-group select="node()" group-ending-with="p[@outputclass='Body_Text']">
<xsl:choose>
<xsl:when test="current-group()/self::p[@outputclass='Body_Text']">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<orderedlist type="manual">
<xsl:apply-templates select="current-group()"/>
</orderedlist>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@outputclass='ListN1-Nam']" mode="id-num">
<section level="sect2"  number-type="manual">
<xsl:apply-templates select="title" mode="id-num"/>
</section>
</xsl:template>

<xsl:template match="p[@outputclass='ListN1-Nam']" mode="id-num">
<xsl:variable name="num">
<xsl:analyze-string select="." regex="(w.)s">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:attribute name="num" select="$num"/>
</xsl:template>
<xsl:template match="p[@outputclass='ListN1-Nam']/text()">
<xsl:value-of select="replace(., 'w.s', '$1')"/>
</xsl:template>
<xsl:template match="p[@outputclass='ListN3-Nam']" mode="id-num">
<section level="sect3"  number-type="manual">
<xsl:apply-templates select="title" mode="id-num"/>
</section>
</xsl:template>

<xsl:template match="p[@outputclass='ListN3-Nam']" mode="id-num">
<xsl:variable name="num">
<xsl:analyze-string select="." regex="(d.+?)s">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:attribute name="num" select="$num"/>
</xsl:template>
<xsl:template match="p[@outputclass='ListN3-Nam']/text()">
<xsl:value-of select="replace(., 'd.s', '$1')"/>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text']">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="p[@outputclass='BodyText_Center']">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="p[@outputclass='Normal']">
<item num="{replace(node()[1], '^s+', '')}">
<para><xsl:apply-templates select="node()[position() gt 1]"/></para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Question'][b]">
<item num="{replace(node()[1], '^s+', '')}">
<para><xsl:apply-templates select="node()[position() gt 1]"/></para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Answer'][b]" priority="10">
<item num="{replace(node()[1], '^s+', '')}">
<para><xsl:apply-templates select="node()[position() gt 1]"/></para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Answer']">
<para><xsl:apply-templates/></para>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>

输出我没有部分级别格式,如下所示:

<!DOCTYPE html
PUBLIC "XSLT-compat">
<Body>
<para>AAAA.</para>
<para>AAAA.</para>
<p outputclass="ListN1-Nam"><b>A. Selvam-4, Item 1</b></p>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<p outputclass="ListN3-Nam"><b>1. Selvam-4, Item 1</b></p>
<para>AAAA.</para>
<p outputclass="ListN3-Nam"><b>2. Selvam-4, Item 1</b></p>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<p outputclass="ListN1-Nam"><b>B. Selvam-4, Item 1</b></p>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<orderedlist type="manual">
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
</orderedlist>
</Body>

所需的输出格式为部分级别格式,"ListN1-Nam"标签作为部分主部分和"ListN3-Nam"第二级的 num 属性值,如下所示:

<!DOCTYPE html
PUBLIC "XSLT-compat">
<Body>
<para>AAAA.</para>
<para>AAAA.</para>
<section level="sect2" num="A." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<section level="sect3" num="1." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
</section>
<section level="sect3" num="2." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
</section>
</section>
<section level="sect2" num="B." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<orderedlist type="manual">
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
</orderedlist>
</section>
</Body>

请指教!

提前致谢

您可以使用 xsl:for-each-group/@group-adjacent 按部分或列表执行分组。在这里,我更改了您的"正文"模板并添加了"groupByList"模板。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform 
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="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Body">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="count(self::p[@outputclass='ListN1-Nam'] | preceding-sibling::p[@outputclass='ListN1-Nam'])">
<xsl:choose>
<xsl:when test="current-group()[1]/self::p[@outputclass='ListN1-Nam']">
<xsl:variable name="sect2p" as="element()" select ="."/>
<xsl:variable name="sect2pText" as="xs:string" select="string($sect2p)"/>
<section level="sect2" num="{substring-before($sect2pText,' ')}" number-type="manual">
<title>
<xsl:value-of select="substring-after($sect2pText,' ')"/>
</title>
<xsl:for-each-group select="current-group()[position() gt 1]" group-adjacent="count(self::p[@outputclass='ListN3-Nam'] | preceding-sibling::p[@outputclass='ListN3-Nam'])">
<xsl:choose>
<xsl:when test="current-group()[1]/self::p[@outputclass='ListN3-Nam']">
<xsl:variable name="sect3p" as="element()" select ="."/>
<xsl:variable name="sect3pText" as="xs:string" select="string($sect3p)"/>
<section level="sect3" num="{substring-before($sect3pText,' ')}" number-type="manual">
<title>
<xsl:value-of select="substring-after($sect2pText,' ')"/>
</title>
<xsl:call-template name="groupByList">
<xsl:with-param name="prmTarget" select="current-group()[position() gt 1]"/>
</xsl:call-template>
</section>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="groupByList">
<xsl:with-param name="prmTarget" select="current-group()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</section>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="groupByList">
<xsl:with-param name="prmTarget" select="current-group()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template name="groupByList">
<xsl:param name="prmTarget" as="element()*" required="yes"/>
<xsl:for-each-group select="$prmTarget" group-adjacent="exists(self::p[string(@outputclass) = ('Body_Text','BodyText_Center')])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<orderedlist type="manual">
<xsl:apply-templates select="current-group()"/>
</orderedlist>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text']">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="p[@outputclass='BodyText_Center']">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="p[@outputclass='Normal']">
<item num="{replace(node()[1], '^s+', '')}">
<para>
<xsl:apply-templates select="node()[position() gt 1]"/>
</para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Question'][b]">
<item num="{replace(node()[1], '^s+', '')}">
<para>
<xsl:apply-templates select="node()[position() gt 1]"/>
</para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Answer'][b]" priority="10">
<item num="{replace(node()[1], '^s+', '')}">
<para>
<xsl:apply-templates select="node()[position() gt 1]"/>
</para>
</item>
</xsl:template>
<xsl:template match="p[@outputclass='Body_Text_Answer']">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>

此样式表生成以下输出:

<!DOCTYPE html
PUBLIC "XSLT-compat">
<Body>
<para>AAAA.</para>
<para>AAAA.</para>
<section level="sect2" num="A." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<section level="sect3" num="1." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
</section>
<section level="sect3" num="2." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
</section>
</section>
<section level="sect2" num="B." number-type="manual">
<title>Selvam-4, Item 1</title>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<para>AAAA.</para>
<orderedlist type="manual">
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
<item num="Q:">
<para> Why?</para>
</item>
<item num="Q:">
<para> What?</para>
</item>
<item num="A:">
<para> In.</para>
</item>
<para>The</para>
</orderedlist>
</section>
</Body>

希望这有助于您的样式表开发。

最新更新