我需要使用不同类的普通段作为输出类名称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>
Out put我没有分段级格式化,如下所示:
<!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>
需要的输出格式为分区级格式和&#39; ListN1-Nam&#39;标签为部分主要部分的num属性值和&#39; ListN3-Nam&#39;第二级如下:
<!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>
请建议!
提前致谢
答案 0 :(得分:0)
您可以使用xsl:for-each-group / @ group-adjacent按部分或列表执行分组。在这里,我更改了“Body”模板并添加了“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>
希望这有助于您的样式表开发。