如何创建输入xml的根元素?

时间:2017-08-09 12:46:37

标签: xml xslt xslt-2.0

我需要在输入

中创建其根元素不可用的模板

我用作的XML:

<Body>
<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>

我使用的XSL:

<xsl:template match="p[@outputclass='Body_Text']">
    <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>

输出I&#39;我喜欢:

<Body>

   <para>AAAA.</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>


   <item num="Q:">
      <para> Why?</para>
   </item>

   <item num="Q:">
      <para> What?</para>
   </item>

   <item num="A:">
      <para> In.</para>
   </item>

   <para>The</para>

</Body> 

预期输出将是(需要在所有问答类型结尾处的正常para和orderlist之后关闭项目列表):

<Body>

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


   <para>The</para></item>


   <item num="Q:">
      <para> Why?</para>
   </item>

   <item num="Q:">
      <para> What?</para>
   </item>

   <item num="A:">
      <para> In.</para>


   <para>The</para></item>
   </orderedlist>

</Body>

我需要为问题和答案类型创建根元素(订单列表)。我正在使用XSLT 2.0版。

1 个答案:

答案 0 :(得分:0)

这个问题类似于以下文章:

How to get the normal paras with different outpuclass as a section level tags

但是列表生成要求有点不同。您可以使用xsl:for-each-group / @ group-adjacent来解决此问题。我添加了“Body”模板来控制分组。另一个模板不会改变原始模板。

[样本样式表]

<?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="xml" 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="boolean(self::p[@outputclass='Body_Text'])">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <orderedlist type="manual">
                            <xsl:for-each-group select="current-group()" group-adjacent="boolean(self::p[string(@outputclass) = ('Normal','Body_Text_Question')])">
                                <xsl:choose>
                                    <xsl:when test="current-grouping-key()">
                                        <xsl:apply-templates select="current-group()"/>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <item>
                                            <xsl:attribute name="num" select="replace(current-group()[1]/b[1], '^\s+', '')"/>
                                            <xsl:apply-templates select="current-group()"/>
                                        </item>
                                    </xsl:otherwise>
                                </xsl:choose>
                            </xsl:for-each-group>
                        </orderedlist>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="p[@outputclass='Body_Text']">
        <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">
        <para><xsl:apply-templates select="node() except b[position() eq 1]"/></para>
    </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>

[结果]

<Body>
    <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>
            <para>The</para>
        </item>
        <item num="Q:">
            <para> Why?</para>
        </item>
        <item num="Q:">
            <para> What?</para>
        </item>
        <item num="A:">
            <para> In.</para>
            <para>The</para>
        </item>
    </orderedlist>
</Body>