473,783 Members | 2,475 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Grouping, duplicates Muenchian appears to fail

7 New Member
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,webse rver,switch,ser ver
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,webse rver,router,swi tch,router,serv er
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,webse rver,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,serve r,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 2578
rayt
7 New Member
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
3261
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
1814
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>. My XSL keeps returning zero for the count. The results for the XML/XSLT files below should look like:- Contact # of Visits Account ----------------------------------------------------------
5
2178
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 it from a traditional programming point of view. I have did quite a bit of searching but have found no answers to my particular problem... please read below XML for the problem I am having.
2
2735
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 xmlns:bibxml="http://bibtexml.sf.net/"> <bibxml:entry id="foo01"> <bibxml:article> <bibxml:title>Foo</bibxml:title>
4
3571
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 the preceding-sibling filter, the nodes are properly sorted. Is this a bug in the xslt processor I'm using (.net framework 1.1) or is this correct behaviour? Any alternative solutions that will show me the lowest priced item in each category?...
6
1584
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"/> <Reference name="invoicer_name" value="Bill"/>
2
1704
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 multiple nodes?" I will use an example to try to explain what I need to do and what I have for data. The example might not be very realistic but it's much easier than to try and explain using the scenario I have =P Suppose I had a list of...
1
1687
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 data from the input xml file, but I can't see how to operate on the grouped result to create and output the desired summary data. If someone could give a reference to an example or provide an actual example I'd really apprecaite it.
1
5709
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" project="neptune"/> <file name="potrzebie.dbf" size="1102" project="jupiter"/>
0
9480
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10315
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10083
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9946
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7494
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6737
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5379
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4044
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.