需要传输两个头(h1)元素值

时间:2017-07-31 06:40:20

标签: xml xslt xslt-2.0

我需要传输具有两个h1元素的输入:

我的输入xml文件有两个元素可用

<Body>
<h1>Head1</h1>
<h1>
<img src="https://tneb.com" />
</h1>
<h2>Head2</h2>
<p>Some people</p>
</Body>

XSLT我用于整个xml集合是:

<xsl:template match="Body[h1]">
         <xsl:for-each-group select="*" group-starting-with="h1[not(normalize-space())]">
         <topic outputclass="">
            <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
            <title outputclass="">
               <xsl:apply-templates select="node()"/>
            </title>

            <xsl:for-each-group select="current-group() except ." group-starting-with="h2">

               <xsl:choose>
                  <xsl:when test="self::h2">
                     <topic outputclass="TOPIC">
                        <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                        <title outputclass="Section">
                           <xsl:apply-templates select="node()"/>
                        </title>

                        <body><xsl:apply-templates select="current-group() except ."/></body>
                     </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="img"> 
       <xsl:element name="image">
            <xsl:if test="@src">
              <xsl:attribute name="href"><xsl:value-of select="@src"/></xsl:attribute>
            </xsl:if>
        </xsl:element>
   </xsl:template>

实际上目前我的输出为:

<topic outputclass="" id="topic_1">
   <title outputclass="">Head1</title>
</topic>
Error on line 19 
  SEPM0004: When 'standalone' or 'doctype-system' is specified, the document must be
  well-formed; but this document contains more than one top-level element
  in built-in template rule

但预期产出需要如下:

<topic outputclass="" id="topic_1">
   <title outputclass="">Head1</title>
   <body>
      <image href="https://tneb.com"/>
   </body>
   <topic outputclass="TOPIC" id="topic_2">
      <title outputclass="Section">Head2</title>
      <body>Some people</body>
   </topic>
</topic>

我需要图像值,但我想删除第二个<h1>标记以及<img>标记。请使用此模板向我推荐一些代码。谢谢

1 个答案:

答案 0 :(得分:0)

让我们从输入和所需输出之间的以下依赖关系开始:

  1. &#34;外部&#34;的来源topic元素是(初始)h1元素。 第一个是其他人的头衔和内容(儿童) 是body

  2. 的内容
  3. &#34;其他&#34;之间存在类似的依赖关系。标签(h1除外)。 第一个是#34;内部&#34;的标题。 topic元素和 其他内容(此时文本)是body的内容。

  4. 所以我创建了以下脚本:

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="Body[h1]">
        <xsl:element name="topic">
          <xsl:attribute name="outputclass"/>
          <xsl:attribute name="id" select="'topic_1'"/>
          <xsl:call-template name="topicContent">
            <xsl:with-param name="src" select="h1"/>
          </xsl:call-template>
          <xsl:element name="topic">
            <xsl:attribute name="outputclass" select="'TOPIC'"/>
            <xsl:attribute name="id" select="'topic_2'"/>
            <xsl:call-template name="topicContent">
              <xsl:with-param name="src" select="*[name()!='h1']"/>
              <xsl:with-param name="outClass" select="'Section'"/>
              <xsl:with-param name="copyVariant" select="2"/>
            </xsl:call-template>
          </xsl:element>
        </xsl:element>
      </xsl:template>
    
      <xsl:template name="topicContent">
        <xsl:param name="src"/>
        <xsl:param name="outClass" select="''"/>
        <xsl:param name="copyVariant" select="1"/>
        <xsl:element name="title">
          <xsl:attribute name="outputclass" select="$outClass"/>
          <xsl:value-of select="$src[1]"/>
        </xsl:element>
        <xsl:element name="body">
          <xsl:if test="$copyVariant = 1">
            <xsl:apply-templates select="subsequence($src, 2)/*"/>
          </xsl:if>
          <xsl:if test="$copyVariant != 1">
            <xsl:value-of select="subsequence($src, 2)"/>
          </xsl:if>
        </xsl:element>
      </xsl:template>
    
      <xsl:template match="img">
        <xsl:element name="image">
          <xsl:attribute name="href" select="@src"/>
        </xsl:element>
      </xsl:template>
    </xsl:transform>
    

    匹配img的模板需要&#34;翻译&#34;来源img 元素到目标image(属性名称各自的变化)。

    修改

    如果您有多个h2代码,则匹配Body[h1]的模板 应该如下:

    <xsl:template match="Body[h1]">
      <xsl:element name="topic">
        <xsl:attribute name="outputclass"/>
        <xsl:attribute name="id" select="'topic_1'"/>
        <xsl:call-template name="topicContent">
          <xsl:with-param name="src" select="h1"/>
        </xsl:call-template>
        <xsl:for-each-group select="*[name()!='h1']" group-starting-with="h2">
          <xsl:element name="topic">
            <xsl:attribute name="outputclass" select="'TOPIC'"/>
            <xsl:attribute name="id" select="'topic_2'"/>
            <xsl:call-template name="topicContent">
              <xsl:with-param name="src" select="current-group()"/>
              <xsl:with-param name="outClass" select="'Section'"/>
              <xsl:with-param name="copyVariant" select="2"/>
            </xsl:call-template>
          </xsl:element>
        </xsl:for-each-group>
      </xsl:element>
    </xsl:template>
    

    除了h1以外的所有元素都应该分组,每个元素都开始 使用h2元素。然后,对于每个这样的组,创建一个topic元素和 在里面调用topicContent模板,但这次是src 参数应该是当前组。