如何将不同outpuclass的正常段作为段级标记

时间:2017-08-10 10:33:50

标签: xml xslt

我需要使用不同类的普通段作为输出类名称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>

请建议!

提前致谢

1 个答案:

答案 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>

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