重组节点

时间:2012-05-25 18:45:57

标签: xslt

我有一个带有以下结构的xml

<xml> 
<object context="3-cumulative" > 
  <metadata> 
    <ref cite="4.2" relevance="first.2"/> 
  </metadata> 
<body> 
   <para> 
      <text>  
             applicable on and after December 14,2007. 
      </text> 
   </para> 
 </body> 
</object> 

 <object context="1-cumulative" > 
  <metadata> 
    <ref cite="4.2" relevance="first.1"/> 
  </metadata> 
<body> 
   <para> 
     <text>  
       applicable on and after December 14,2006. 
     </text> 
   </para> 
</body> 
 </object> 


   <object context="1-cumulative" > 
   <metadata> 
      <related-content-ref cite="5 annuity" relevance="first.1"/> 
   </metadata> 
  <body> 
    <para> 
      <text> 
         applicable on and after December 14, 2008 
      </text> 
     </para> 
   </body> 
  </object> 


   <mainbody> 
        <num cite="4.2">4.2</num> 
        <num cite="2" type="para">2</num> 
        <heading>Stock exchanges</heading> 
        <prov-body> 
          <text> 
              Notwithstanding the provisions of a convention ... as defined in the 
              <italic>Income Tax Act</italic>. 
          </text> 
            <prov> 
              <num cite="1 annuity"/> 
              <num cite="5 annuity"/> 
              <num cite="3 annuity"/> 

                 <heading>“annuity”</heading> 
                <text> 
                <term>“annuity”</term>does not include any pension payment ... 
                </text> 
               <text> 
                 any pension payment ... 
               </text> 
           </prov> 
       </prov-body> 
      </mainbody> 
    </xml>   

我需要,如果在“mainbody”中找到任何object / metadata / ref / @ cite,则num / @ cite和object / @ context为'1-cumulative',则对象的para / text应该在末尾复制第一个Text节点,应按对象/元数据/ ref / @相关性排序,或者如果在“mainbody”中找到任何object / metadata / ref / @ cite,则num / @ cite和object / @ context为'3-cumulative'然后来自对象的para / text应该在第一个Text节点之后用它自己的Text elemet复制,并且应该按object / metadata / ref / @ related

排序

输出应为:

<xml> 
 <mainbody> 
 <num cite="4.2">4.2</num> 
 <num cite="2" type="para">2</num> 
 <heading>Stock exchanges</heading> 
 <prov-body> 
  <text> 
    Notwithstanding the provisions of a convention ... as defined in the 
    <italic>Income Tax Act</italic>. 
    **applicable on and after December 14, 2006** 
  </text> 
  <text>   **applicable on and after December 14, 2007** </text>

 <prov> 
        <num cite="1 annuity"/> 
        <num cite="5 annuity"/> 
        <num cite="3 annuity"/> 
        <heading>“annuity”</heading> 
        <text> 
        <term>“annuity”</term>does not include any pension payment ... 
         **applicable on and after December 14, 2008** 
        </text> 
        <text> 
        any pension payment ... 
       </text> 
   </prov> 
  </prov-body> 
 </mainbody> 
</xml>   

1 个答案:

答案 0 :(得分:0)

此转化

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:key name="kRefByCite"
          match="metadata/*" use="@cite" />

     <xsl:key name="kRefByCite1"
          match="*[@context='1-cumulative']/metadata/*"
          use="@cite" />

     <xsl:key name="kRefByCite3"
          match="*[@context='3-cumulative']/metadata/*"
          use="@cite" />

     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>

     <xsl:template match=
       "text[not(preceding-sibling::text[1])
           and
             preceding::num
                  [key('kRefByCite', @cite)]]">
       <text>
         <xsl:apply-templates/>
         <xsl:for-each select=
           "key('kRefByCite1', (.|..)/preceding-sibling::num/@cite)">
           <xsl:sort select="@relevance"/>

           <xsl:value-of select="../../body/para/text"/>
         </xsl:for-each>
       </text>
       <xsl:for-each select=
         "key('kRefByCite3', (.|..)/preceding-sibling::num/@cite)">
         <xsl:sort select="@relevance"/>

         <text><xsl:value-of select="../../body/para/text"/></text>
       </xsl:for-each>

     </xsl:template>

     <xsl:template match=
       "node()
          [parent::* and not(ancestor-or-self::mainbody)]"/>
</xsl:stylesheet>

应用于提供的XML文档

<xml>
    <object context="3-cumulative" >
      <metadata>
        <ref cite="4.2" relevance="first.2"/>
      </metadata>
    <body>
       <para>
          <text>
                 applicable on and after December 14,2007.
          </text>
       </para>
     </body>
    </object>

     <object context="1-cumulative" >
      <metadata>
        <ref cite="4.2" relevance="first.1"/>
      </metadata>
    <body>
       <para>
         <text>
           applicable on and after December 14,2006.
         </text>
       </para>
    </body>
     </object>


       <object context="1-cumulative" >
       <metadata>
          <related-content-ref cite="5 annuity" relevance="first.1"/>
       </metadata>
      <body>
        <para>
          <text>
             applicable on and after December 14, 2008
          </text>
         </para>
       </body>
      </object>


       <mainbody>
            <num cite="4.2">4.2</num>
            <num cite="2" type="para">2</num>
            <heading>Stock exchanges</heading>
            <prov-body>
              <text>
                  Notwithstanding the provisions of a convention ... as defined in the
                  <italic>Income Tax Act</italic>.
              </text>
                <prov>
                  <num cite="1 annuity"/>
                  <num cite="5 annuity"/>
                  <num cite="3 annuity"/>

                     <heading>“annuity”</heading>
                    <text>
                    <term>“annuity”</term>does not include any pension payment ...
                    </text>
                   <text>
                     any pension payment ...
                   </text>
               </prov>
           </prov-body>
          </mainbody>
</xml>

会产生想要的正确结果:

<xml>
   <mainbody>
      <num cite="4.2">4.2</num>
      <num cite="2" type="para">2</num>
      <heading>Stock exchanges</heading>
      <prov-body>
         <text>
                  Notwithstanding the provisions of a convention ... as defined in the
                  <italic>Income Tax Act</italic>.

           applicable on and after December 14,2006.
         </text>
         <text>
                 applicable on and after December 14,2007.
          </text>
         <prov>
            <num cite="1 annuity"/>
            <num cite="5 annuity"/>
            <num cite="3 annuity"/>
            <heading>“annuity”</heading>
            <text>
               <term>“annuity”</term>does not include any pension payment ...

             applicable on and after December 14, 2008
          </text>
            <text>
                     any pension payment ...
                   </text>
         </prov>
      </prov-body>
   </mainbody>
</xml>