xsl-list
[Top] [All Lists]

Re: [xsl] FW: XSLT newbie

2006-12-27 09:53:08
I am assuming you want to solve this problem using XSLT 1.0. I have
used the nodeset extension function in my solution below.

Here is a solution you might find useful.

The input XMLs are:

paths.xml
--------------

<Paths>
 <path1>books.book.author.name</path1>
 <path2>books.book.name</path2>
</Paths>

input.xml
-------------

<books>
 <book>
   <name>a1</name>
   <price>10</price>
   <author>
     <name>b1</name>
     <gender>m</gender>
   </author>
 </book>
 <book>
   <name>a2</name>
   <price>10</price>
   <author>
     <name>b2</name>
     <gender>f</gender>
   </author>
 </book>
</books>

The stylesheet is:

test.xsl
-----------

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                      xmlns:xalan="http://xml.apache.org/xalan";
                      version="1.0">

<xsl:output method="text" />

<xsl:variable name="doc2" select="document('input.xml')" />

<xsl:template match="/Paths">

 <!-- iterate over all child elements -->
 <xsl:for-each select="*">
   <!-- strore path in a variable -->
   <xsl:variable name="path1">
     <xsl:call-template name="ConstructPath1">
       <xsl:with-param name="x" select="." />
       <xsl:with-param name="result" select="''" />
     </xsl:call-template>
   </xsl:variable>

   <!-- accumulate output -->
   <xsl:variable name="rtf">
     <xsl:for-each select="$doc2//*">
       <!-- strore path in a variable -->
       <xsl:variable name="path2">
         <xsl:call-template name="ConstructPath2">
           <xsl:with-param name="x" select="." />
           <xsl:with-param name="result" select="''" />
         </xsl:call-template>
       </xsl:variable>

       <!-- compare paths -->
       <xsl:if test="$path1 = $path2">
         <dummy><xsl:value-of select="$path1" /></dummy>
       </xsl:if>
     </xsl:for-each>
   </xsl:variable>

   <!-- eliminate duplicates from accumulated output; and print result -->
   <xsl:for-each select="xalan:nodeset($rtf)/dummy[not(. =
preceding-sibling::*)]">
     <xsl:value-of select="." /> : exists <xsl:text>&#xa;</xsl:text>
   </xsl:for-each>
 </xsl:for-each>
</xsl:template>

<!-- construct path, given a string of form x.y.z -->
<xsl:template name="ConstructPath1">
 <xsl:param name="x" />
 <xsl:param name="result" />

 <xsl:choose>
   <xsl:when test="contains($x, '.')">
     <xsl:call-template name="ConstructPath1">
       <xsl:with-param name="x" select="substring-after($x, '.')" />
       <xsl:with-param name="result" select="concat($result, '/',
substring-before($x, '.'))" />
     </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
     <xsl:choose>
       <xsl:when test="string-length($x) &gt; 0">
         <xsl:value-of select="concat($result, '/', $x)" />
       </xsl:when>
       <xsl:otherwise>
         <xsl:value-of select="$result" />
       </xsl:otherwise>
     </xsl:choose>
   </xsl:otherwise>
 </xsl:choose>
</xsl:template>

<!-- construct element path, given an element node as input -->
<xsl:template name="ConstructPath2">
 <xsl:param name="x" />
 <xsl:param name="result" />

 <xsl:choose>
   <xsl:when test="$x/..">
     <xsl:call-template name="ConstructPath2">
       <xsl:with-param name="x" select="$x/.." />
       <xsl:with-param name="result" select="concat('/',
local-name($x), $result)" />
     </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
     <xsl:value-of select="$result" />
   </xsl:otherwise>
 </xsl:choose>
</xsl:template>

</xsl:stylesheet>

This when run with Xalan-J 2.7.1 as following:

java org.apache.xalan.xslt.Process -in paths.xml -xsl test.xsl

produces output:

/books/book/author/name : exists
/books/book/name : exists

Hope this helps.

On 12/27/06, Thimmegowda, Balaji <balaji_thimmegowda(_at_)merck(_dot_)com> 
wrote:
Hi,

I am trying to achieve the following using XSLT :

I apply a XSLT on my source XML to get a path - say, books/author/name

Now, I want to see if this node exists in another xml. Is there a way by
which this can be achieved using XSLT ?


Sample Source XML : The dots are used as delimiters and will later be
replaced to slashes in the XSLT.

Paths.xml

<Paths>
       <path1>books.book.author.name</path1>
       <path2>books.book.name</path2>
</Paths>

------------------------------------------------------------------------
-------------

Sample Input XML.

Input.xml

<books>
       <book>
               <name>a1</book>
               <price>10</price>
               <author>
                       <name>b1</name>
                       <gender>m</gender>
               </author>
       </book>
       <book>
               <name>a2</book>
               <price>10</price>
               <author>
                       <name>b2</name>
                       <gender>f</gender>
               </author>
       </book>
</books>


The XSLT should first get the path from the paths.xml and search the
Input.xml to see if the node specified by the path exists. Can somebody
please let me know how to go about solving this.

Regards,
BT


------------------------------------------------------------------------------
Notice:  This e-mail message, together with any attachments, contains
information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station,
New Jersey, USA 08889), and/or its affiliates (which may be known
outside the United States as Merck Frosst, Merck Sharp & Dohme or MSD
and in Japan, as Banyu - direct contact information for affiliates is
available at http://www.merck.com/contact/contacts.html) that may be
confidential, proprietary copyrighted and/or legally privileged. It is
intended solely for the use of the individual or entity named on this
message. If you are not the intended recipient, and have received this
message in error, please notify us immediately by reply e-mail and then
delete it from your system.


--
Regards,
Mukul Gandhi

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>