473,395 Members | 1,456 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Grouping, duplicates Muenchian appears to fail

7
I’m relatively new to XSLT and must admit I’m finding it refreshing, but every now and again something comes along which floors me. Maybe it’s the old imperative language background that is hard to shake. This is an example of a dark cloud in my brave new declarative world. Clearing duplication is bread and butter but in XSLT it’s not. The old preceding axis method is both too slow and destined to failure. The Muenchian method, although sublime to the novice also seems to become unstuck (have I missed something obvious). I cast my sanity and naivety over to the community.

The XML included is a psuedo subset of a much larger file, which is generated from a network management system. Each submap tag contains a collection of devices and essentially other submaps which in-turn can contain a collection of devices and submaps and so on.

The problem is, given a submap level that can be passed as a parameter into the stylesheet. I need to form a unduplicated list of groups ( node grps) contained within the submap nodes at the current context of interest. This includes submaps which are descendants of each of the submaps of the context of interest. Let me get the XML and an example of the target output needed this is getting too wordy already.


XML

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <root>
  3.     <submap name="A">
  4.         <device>
  5.             <devname>rtr001</devname>
  6.             <grp>router</grp>
  7.         </device>
  8.         <submap name="E">
  9.             <device>
  10.                 <devname>rtr005</devname>
  11.                 <grp>router</grp>
  12.             </device>
  13.             <device>
  14.                 <devname>SW0001</devname>
  15.                 <grp>switch</grp>
  16.             </device>
  17.         </submap>
  18.     </submap>
  19.     <submap name="B">
  20.         <submap name="F">
  21.             <submap name="G">
  22.                 <submap name="H">
  23.                     <device>
  24.                         <devname>ftp003</devname>
  25.                         <grp>ftpserver</grp>
  26.                     </device>
  27.                     <device>
  28.                         <devname>www001</devname>
  29.                         <grp>webserver</grp>
  30.                     </device>
  31.                 </submap>
  32.                 <device>
  33.                     <devname>rtr007</devname>
  34.                     <grp>router</grp>
  35.                 </device>
  36.                 <device>
  37.                     <devname>SW0002</devname>
  38.                     <grp>switch</grp>
  39.                 </device>
  40.                 <device>
  41.                     <devname>rtr006</devname>
  42.                     <grp>router</grp>
  43.                 </device>
  44.                 <device>
  45.                     <devname>srv001</devname>
  46.                     <grp>server</grp>
  47.                 </device>
  48.             </submap>
  49.         </submap>
  50.         <device>
  51.             <devname>rtr002</devname>
  52.             <grp>router</grp>
  53.         </device>
  54.         <submap name="I">
  55.             <device>
  56.                 <devname>rtr005</devname>
  57.                 <grp>router</grp>
  58.             </device>
  59.             <device>
  60.                 <devname>hub001</devname>
  61.                 <grp>hub</grp>
  62.             </device>
  63.         </submap>
  64.     </submap>
  65.     <submap name="C">
  66.         <submap name="j">
  67.             <device>
  68.                 <devname>rtr006</devname>
  69.                 <grp>router</grp>
  70.             </device>
  71.             <device>
  72.                 <devname>av0001</devname>
  73.                 <grp>antivirus</grp>
  74.             </device>
  75.         </submap>
  76.         <device>
  77.             <devname>rtr003</devname>
  78.             <grp>router</grp>
  79.         </device>
  80.     </submap>
  81.     <submap name="D">
  82.         <device>
  83.             <devname>rtr004</devname>
  84.             <grp>router</grp>
  85.         </device>
  86.         <device>
  87.             <devname>pop001</devname>
  88.             <grp>mailserver</grp>
  89.         </device>
  90.     </submap>
  91. </root>
Target Output ( using target submap B – Context node)

Groups for submaps in B context.

Submap F - router ftpserver,webserver,switch,server
Submap I – router,hub




What I can get, and what I have tried and failed at

What is possible?

A list of all down stream grps split by submap but containing duplicates.

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:param name="targetsubmap">B</xsl:param>
  4.  
  5. <xsl:template match="/">
  6. <xsl:apply-templates select="//submap[@name=$targetsubmap]" mode="test"/>
  7. </xsl:template>
  8.  
  9. <xsl:template match="submap" mode="test">
  10. <xsl:text>
  11. Groups for submaps in </xsl:text><xsl:value-of select="@name"/><xsl:text> context.
  12. </xsl:text>
  13. <xsl:apply-templates select="submap" mode="level">
  14. </xsl:apply-templates>
  15. </xsl:template>
  16. <xsl:template match="submap" mode="level">
  17. <xsl:text>
  18. Submap </xsl:text>
  19. <xsl:value-of select="@name"/><xsl:text> - </xsl:text>
  20. <xsl:for-each select="descendant::grp">
  21. <xsl:value-of select="."/>
  22. <xsl:if test="position() != last()">,</xsl:if>
  23. </xsl:for-each>
  24. </xsl:template>
  25.  
  26. </xsl:stylesheet>

Output

Groups for submaps in B context.

Submap F - ftpserver,webserver,router,switch,router,server
Submap I - router,hub

Note router is duplicated in submap F list, it should be in submap I list

What also fails.

The Muenchian Method

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:param name="targetsubmap">B</xsl:param>
  4. <xsl:key name="kdgroups" match="//device" use="grp"/>
  5.  
  6. <xsl:template match="/">
  7. <xsl:apply-templates select="//submap[@name=$targetsubmap]" mode="test"/>
  8. </xsl:template>
  9.  
  10. <xsl:template match="submap" mode="test">
  11. <xsl:text>
  12. Groups for submaps in </xsl:text><xsl:value-of select="@name"/><xsl:text> context.
  13. </xsl:text>
  14. <xsl:apply-templates select="submap" mode="level">
  15. </xsl:apply-templates>
  16. </xsl:template>
  17.  
  18. <xsl:template match="submap" mode="level">
  19. <xsl:text>
  20. Submap </xsl:text>
  21. <xsl:value-of select="@name"/><xsl:text> - </xsl:text>
  22. <xsl:for-each select="descendant::device[generate-id(.)=generate-id(key('kdgroups',grp))]">
  23. <xsl:value-of select="grp"/>
  24. <xsl:if test="position() != last()">,</xsl:if>
  25. </xsl:for-each>
  26. </xsl:template>
  27.  
  28. </xsl:stylesheet>
OUTPUT

Groups for submaps in B context.

Submap F - ftpserver,webserver,server
Submap I - hub

This seems to fail because, once an id is generated(see what happens to the router group) it is no longer available to subsequent submaps so it is not included within the output tree as needed. Adding the context to the key declaration would reduce the amount of elements the key is applied to but would still fail. The router and switch groups would appear in the submap F list but not the submap I list as needed. Also the context is passed in as a parameter that cannot appear in the match clause of the key declaration.

The preceding axis solution as per O’Reiley Cookbook – although probably way to slow on a larger file. I attempted this method just in-case. It fails for the same reason as the Muenchian Method. Can any one explain the trailing comma?

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:param name="targetsubmap">B</xsl:param>
  4.  
  5. <xsl:template match="/">
  6. <xsl:apply-templates select="//submap[@name=$targetsubmap]" mode="test"/>
  7. </xsl:template>
  8.  
  9. <xsl:template match="submap" mode="test">
  10. <xsl:text>
  11. Groups for submaps in </xsl:text><xsl:value-of select="@name"/><xsl:text> context.
  12. </xsl:text>
  13. <xsl:apply-templates select="submap" mode="level">
  14. </xsl:apply-templates>
  15. </xsl:template>
  16.  
  17. <xsl:template match="submap" mode="level">
  18. <xsl:text>
  19. Submap </xsl:text>
  20. <xsl:value-of select="@name"/><xsl:text> - </xsl:text>
  21. <xsl:for-each select="descendant::grp">
  22. <xsl:sort select="."/>
  23. <xsl:if test="not(self::node()=preceding::node())">
  24. <xsl:value-of select="."/>
  25. <xsl:if test="position() != last()">,</xsl:if>
  26. </xsl:if>
  27. </xsl:for-each>
  28. </xsl:template>
  29.  
  30. </xsl:stylesheet>

Output

Groups for submaps in B context.

Submap F - ftpserver,server,webserver
Submap I - hub,

If anybody finds a solution which requires the source XML to be altered this is ok as I wrote the Interface to the Network Management System so I can change it. I should note that the XML you can see is a massively simplified abstraction to demonstrate the point. Basically if I have to change it I will.

Hopefully thanks for the help, let me know any methods you have tried even if they fail so I can tick them of the list. I’m hoping I have misunderstood Muenchian.
Oct 6 '05 #1
1 2559
rayt
7
At last I’ve got the swine, well almost, I need to fix the trailing comma (<xsl:if test="position() != last()">,</xsl:if> does not work as I cannot guarantee position).


I know it probably has flaws but it works. If anybody has a better way could you let me know or if anybody knows a clever way to get rid of the trailing comma I’d be grateful.


Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:param name="targetsubmap">B</xsl:param>
  4. <xsl:key name="kdgroups" match="//device" use="grp"/>
  5.  
  6. <xsl:template match="/">
  7. <xsl:apply-templates select="//submap[@name=$targetsubmap]" mode="test"/>
  8. </xsl:template>
  9.  
  10. <xsl:template match="submap" mode="test">
  11. <xsl:text>
  12. Groups for submaps in </xsl:text><xsl:value-of select="@name"/><xsl:text> context.
  13. </xsl:text>
  14. <xsl:apply-templates select="submap" mode="level">
  15. </xsl:apply-templates>
  16. </xsl:template>
  17.  
  18. <xsl:template match="submap" mode="level">
  19. <xsl:variable name="cursub" select="."/>
  20. <xsl:variable name="totgrps" select="//device[generate-id(.)=generate-id(key('kdgroups',grp))]"/>
  21. <xsl:text>
  22. Submap </xsl:text>
  23. <xsl:value-of select="@name"/>
  24. <xsl:text> - </xsl:text>
  25. <xsl:for-each select="$totgrps">
  26. <xsl:variable name="loopgrp" select="grp"/>
  27. <xsl:for-each select="$cursub">
  28. <xsl:if test="count(descendant::device[grp=$loopgrp]) > 0">
  29. <xsl:value-of select="$loopgrp"/>
  30. <xsl:text>,</xsl:text>
  31. </xsl:if>
  32. </xsl:for-each>
  33. </xsl:for-each>
  34. </xsl:template>
  35.  
  36. </xsl:stylesheet>
Oct 9 '05 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: Bryce (Work) | last post by:
Here is the xml I'm working with: <result> <EFORM> <testNode> <section1> <string1>ADAM</string1> <integer1>55</integer1> </section1> </testNode>
3
by: Graham | last post by:
Hi, I am having trouble getting XSL to count the members of a group. What I am trying to do is group by <objectid.Contactid> and count the number of <activityid>'s for each <objectid.contactid>....
5
by: Jody Greening | last post by:
Transforming with XSLT, Grouping elements until difference found. I am seeking some help with the following problem, I am fairly new at XSLT transformations, and my problem may lie in looking at...
2
by: Tristan Miller | last post by:
Greetings. I have a question involving sorting and grouping output using XSLT. I am trying to produce a publication list from a BibTeX-like XML file: <bibxml:file...
4
by: kristofera | last post by:
I am trying to do a distinct grouping of some nodes sorted by a numeric value but for some reason the distinct (preceding-sibling filter) is applied to the result as if not sorted. If I don't use...
6
by: Per Jørgen Vigdal | last post by:
I have a XML that I need to map. The XML goes like: <Children> <Child> <References> <External> <Reference name="filename" value="1.dat"/> <Reference name="invoicenr" value="1111111"/>...
2
by: Andreas Håkansson | last post by:
Seeing how my previous post seem to have fallen between the cracks, I thought I would have a second, more direct, go at it. So my question is "Is it possible to group (Muenchian method) over...
1
by: lennyw | last post by:
Hi I'm trying to use XSLT to do an xml to xml transformation where the output xml contains summary data on the information in the input xml. I've succesfully done a Muenchian grouping of the...
1
by: Sandeep Singh | last post by:
Hi, How to do group by in XSLT ? I tried on the following codes: <files> <file name="swablr.eps" size="4313" project="mars"/> <file name="batboy.wks" size="424" ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.