[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

XSLT, Identity transformation and XML

Posted on 2004-09-24
8
Medium Priority
?
708 Views
Last Modified: 2008-03-10
Hi,

Today I use identity transform. to filter elements from my original XML file and create XML output file.
I have created two XSLTs (base.xslt and filter.xslt), where base.xslt does the identity transformation and filter.xslt defines filtering rules and templates.

What I basically want is to filter elements of type "sub" and sort them under one parent node and make selections of type "main" and sort them under another parent node. One parent node for each category. (see in Filtered XML how output shoul look like).

My input XML looks like:

[Original XML]

<Documents>
    <Document chapter="1" title="title 1" href="file1.xml">
          <Article title="1.1" info="sub"/>
          <Article title="1.2" info="main"/>          
     </Document>
    <Document chapter="2" title="title 2" href="file2.xml">
          <Article title="2.1" info="sub"/>
          <Article title="2.2" info="main"/>          
     </Document>
</Documents>


[Filtered XML SHOULD LOOK LIKE]

<Documents>
    <Document name="main">
          <Article title="1.2" info="main"/>
          <Article title="2.2" info="main"/>
     </Document>
    <Document name="sub">
          <Article title="1.1" info="sub"/>        
          <Article title="2.1" info="sub"/>          
     </Document>
</Documents>


[base.xslt]

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
     <!-- Import filter rules -->
        <xsl:include href="filter.xslt"/>

     <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     <xsl:template match="node() | @*">
          <xsl:copy>
               <xsl:apply-templates select="node() | @*"/>
          </xsl:copy>
     </xsl:template>
</xsl:stylesheet>


[filter.xslt]

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
            <xsl:template match="Doc[not(@info='main')][not(@info='sub')]"/>
</xsl:stylesheet>


thnx.

-J
0
Comment
Question by:morpheous_
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
8 Comments
 
LVL 15

Expert Comment

by:dualsoul
ID: 12146895
hm...morpheous_ , but this is outputs:

<Documents>
    <Document name="main">
          <Article title="1.2" info="main"/>
          <Article title="2.2" info="main"/>
     </Document>
    <Document name="sub">
          <Article title="1.1" info="sub"/>        
          <Article title="2.1" info="sub"/>          
     </Document>
</Documents>


 - doesn't it what you want? not?
0
 

Author Comment

by:morpheous_
ID: 12147911
I want output to look something like that.
I would like to create parent nodes that group filtered elements, so each element group (e.g. info="main") is sorted under one parent node, and other element group (e.g. info="sub") is sorted under other parent node.

The above is just the example how it supposed to look like, if I send the ORIGINAL.XML trough  FILTER.XML.
So, I would need to define rules in Filter.xml (or similar) that create output like the one below:

<Documents>
    <Document name="main">
          <Article title="1.2" info="main"/>
          <Article title="2.2" info="main"/>
     </Document>
    <Document name="sub">
          <Article title="1.1" info="sub"/>        
          <Article title="2.1" info="sub"/>          
     </Document>
</Documents>
0
 

Author Comment

by:morpheous_
ID: 12156327
what differs is that I would like to generate parent nodes groups automatically based on the filtered elements.
e.g. if elements info=main are filtered, then they should be grouped under it's own parent node group called "main" (like in the output example above), same with the other filtered element "sub" should have it's own group.

So, the pseudo should look something like this:

1. filter all elements where attribute info="main"
2. create parent node called "main" for elements where info="main"
3. place elements (Article) of attribute info="main" under parent node "main"

and so on iterate, untill original, input XML is filtered completely of the keywords located in filter.xslt

 <xsl:template match="Doc[not(@info='main')][not(@info='sub')]"/>



    <Document title="main">
          <Article title="1.2" info="main"/>
          <Article title="2.2" info="main"/>
     </Document>
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 15

Expert Comment

by:dualsoul
ID: 12167894
it seems i confused, can you post sample and result for it.
0
 

Accepted Solution

by:
morpheous_ earned 0 total points
ID: 12178747
I wanted to group Article elements by their info attribute.

I have found a solution.

By using Muenchian Method, I am able to group elements under parent nodes created from the filtered elemtens groups.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
   <xsl:key name="by-info" match="Article" use="@info"/>
   <xsl:template match="/Documents">
       <Documents>
           <xsl:for-each select="Document/Article[count(.|key('by-info', @info)[1])=1]">
               <Document name="{@info}">
                   <xsl:copy-of select="key('by-info', @info)"/>
               </Document>
           </xsl:for-each>
       </Documents>
   </xsl:template>
</xsl:stylesheet>


More about Muenchian method @ http://www.jenitennison.com/xslt/grouping/muenchian.html


Regards,

-xrow
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 12198688
morpheous_ , i'm glad you've found a solution yourself.

Sorry, i was really busy at work, and was unable to dig your problem.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question