Solved

XSLT, Identity transformation and XML

Posted on 2004-09-24
8
678 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_
  • 3
  • 3
8 Comments
 
LVL 15

Expert Comment

by:dualsoul
Comment Utility
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_
Comment Utility
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_
Comment Utility
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 Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 15

Expert Comment

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

Accepted Solution

by:
morpheous_ earned 0 total points
Comment Utility
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
Comment Utility
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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now