1

I have a following 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="3-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="3-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>
      <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="5 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>  

I need to see if any object/metadata/ref/@cite has been found in "mainbody" num/@cite then para/text from object should copy at the end of first Text node and should be sort by object/metadata/ref/@relevance.

The output should be:

<xml>
 <mainbody>
 <num cite="4.2">4.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**
    **applicable on and after December 14, 2007**
  </text>
 <prov>
        <num cite="5 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>  
3
  • what are you waiting for? let us know when you run into problems! Commented May 23, 2012 at 23:00
  • I just want to know how to start it, i am using key to get the cites from object/metadata/ref/@cite, how do i match the text emlment? I need first text element of each set where we have matching cite. Commented May 23, 2012 at 23:34
  • Your sample "expected output" is not well-formed. Please correct. <xml> is not a permissible element name, and even if it was, there is no matching ending tag to this starting tag. Commented May 24, 2012 at 0:33

1 Answer 1

2

This XSLT 1.0 transformation (the same result is produced if the version attribute is changed to 2.0 and the transformation is run with an XSLT 2.0 processor):

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

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

       <xsl:value-of select="../../body/para/text"/>
     </xsl:for-each>
   </text>
 </xsl:template>
 <xsl:template match=
   "node()
    [parent::* and not(ancestor-or-self::mainbody)]"/>
</xsl:stylesheet>

when applied on the provided XML document:

<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="3-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="3-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>
        <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="5 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>

produces the wanted, correct result:

<xml>
   <mainbody>
      <num cite="4.2">4.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.

          applicable on and after December 14,2007.
                </text>
         <prov>
            <num cite="5 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>

Explanation:

Appropriate overriding of the identity rule and use of xsl:key and the key() function.

Sign up to request clarification or add additional context in comments.

6 Comments

Wow... Thanks alot. It worked like a charme, just modifed <xsl:sort select="@cite"/> to <xsl:sort select="@relevance"/>. Just need an addtional stuuf <object context="3-cumulative" > based on context type is want to insert values before and after the text element. so if type= "3-cumulative" then it should wrok as above. If type = "1-cummlative" then instead of interting with in text i want it to be before <text> and if it's 2-commulative then insert after </text>.
I did try doing like that <xsl:variable name="context" select="../../@context"/> <xsl:if test="$context = '3-cumulative' "> <text> <xsl:apply-templates/> </text> <xsl:value-of select="../../body/para/text"/> </xsl:if> but not the desire result... any thought Dimitre?
@atif: Your original question is fully answered. There may be infinite "small" modifications of the original question and it wouldn't be correct to add them as minor changes to the question. Please, think well what exactly is needed and ask a new question. It is nighttime here, so I would be glad to have a look tomorrow morning at any new question that you might have posted.
Dimitre, I am able to resolve above mentioned comments but I am stuck with if I have 2 num nodes in i-e <mainbody> <num cite="4.2">4.2</num> <num cite="123">123</num> It looks for last num, if there a possibilty that we look for all num values in tempalte match <xsl:template match= "text[(preceding::text[1]|preceding::num[1]) [last()] [key('kRefByCite', @cite)]]"> ???
@atif: The comments format isn't good for posting comments. Please, ask a new question and I'll be glad to answer. Include a complete instance of the new XML, all the rules that the transformation must implement and the complete wanted result.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.