Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 14th, 2010, 06:14 AM
Authorized User
 
Join Date: Jul 2010
Posts: 27
Thanks: 6
Thanked 0 Times in 0 Posts
Default How to check whether an elements contains another elements or not?

I have the source xml document:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<listbox>
	<box id="a1" size="24">
		<numberofball>3</numberofball>
	</box>
	<box id="a2" size="64">
		<numberofball>3</numberofball>
	</box>
	<box id="a3" size="36">
		<numberofball>3</numberofball>
	</box>
	<box id="a4" size="42"/>
	<box id="a5" size="43"/>
</listbox>
And I wanna export to following document:
Code:
<categorybox>
	<notemptybox>a1</notemptybox>
	<notemptybox>a2</notemptybox>
	<notemptybox>a3</notemptybox>
	<emptybox>a4</emptybox>
	<emptybox>a5</emptybox>
</categorybox>
Could anybody help me?
 
Old August 14th, 2010, 06:21 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Sure, XSLT is very good at this sort of job. You just need three rules:

Code:
<xsl:template match="box[numberofball]">
  <notemptybox><xsl:value-of select="@id"/></notemptybox>
</xsl:template>

<xsl:template match="box">
  <emptybox><xsl:value-of select="@id"/></emptybox>
</xsl:template>

<xsl:template match="listbox">
  <categorybox><xsl:apply-templates/></categorybox>
</xsl:template>
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
metinhoclam (August 14th, 2010)
 
Old August 14th, 2010, 09:49 AM
Authorized User
 
Join Date: Jul 2010
Posts: 27
Thanks: 6
Thanked 0 Times in 0 Posts
Default Check function

Dear Mr.mhkay

Is there any fuction to check whether element contain another element. In case of the <box> is not only as unique element inside <listbox>.
I've made the parent template with: <xsl:apply-templates select ="listcontainer/*". Could I do like <xsl:template match="*[numberofball]" ?

To get clearly, this is source document:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<listcontainer>
	<box id="a1" size="24" status="saled">
		<numberofball>3</numberofball>
	</box>
	<box id="a2" size="64" status="instore">
		<numberofball>3</numberofball>
	</box>
	<box id="a3" size="36" status="instore">
		<numberofball>3</numberofball>
	</box>
	<box id="a4" size="42" status="instore"/>
	<box id="a5" size="43" status="saled"/>
	
	<bag id ="b1" sive="16x20" status="instore"><numberofbook>12</numberofbook></bag>
	<bag id ="b2" sive="10x10" status="instore"><numberofbook>8</numberofbook></bag>
	<bag id ="b3" sive="16x10" status="instore"><numberofbook>10</numberofbook></bag>
	<bag id ="b4" sive="16x20" status="saled"/ ></bag>
	<bag id ="b5" sive="16x20"><numberofbook>13</numberofbook></bag>
	
	<can id = "c1" size ="100m3" status="instore"><oil>3l</oil></can>
	<can id = "c2" size ="120m3" status="saled"><oil>4l</oil></can>
	<can id = "c3" size ="200m3" status="instore"></can>
	<can id = "c4" size ="210m3" status="saled"><oil>4l</oil></can>
	<can id = "c5" size ="220m3" status="instore"><oil>5l</oil></can>
	<can id = "c6" size ="300m3" status="saled" ><oil>13l</oil></can>

</listcontainer>
</root>
And this is the expectation xml document
Code:
<goods_status>
<saled_goods>
	<empty_box>a5</empty_box>
	<notempty_box>a1</notempty_box>

.....
	<empty_bag>b4</empty_bag>
	<notempty_bag></notempty_bag>
	<empty_can></empty_can>
	<notempty_can></notempty_can>
</saled_goods>

<instore_goods>
	<notempty_box>a2</notempty_box>
	<notempty_box>a3</notempty_box>
	<empty_box>a4</empty_box>
	<empty_bag></empty_bag>
	<notempty_bag></notempty_bag>
	<empty_can></empty_can>
	<notempty_can></notempty_can>
</instore_goods>
</goods_status>

Last edited by metinhoclam; August 14th, 2010 at 09:56 AM..
 
Old August 14th, 2010, 09:56 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

It looks as if you want to group the child elements of the "listcontainer" element by the "status" attribute. Do you use XSLT 2.0 or 1.0? With 2.0 you can use for-each-group select="*" group-by="status". With XSLT 1.0 you need Muenchian grouping http://www.jenitennison.com/xslt/grouping/muenchian.xml
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old August 14th, 2010, 09:59 AM
Authorized User
 
Join Date: Jul 2010
Posts: 27
Thanks: 6
Thanked 0 Times in 0 Posts
Default altova spy

Dear Mr.mhkay
I'm using altova spy and I declare with xslt version 2.0
 
Old August 14th, 2010, 10:11 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

If the input is
Code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<listcontainer>
    <box id="a1" size="24" status="saled">
        <numberofball>3</numberofball>
    </box>
    <box id="a2" size="64" status="instore">
        <numberofball>3</numberofball>
    </box>
    <box id="a3" size="36" status="instore">
        <numberofball>3</numberofball>
    </box>
    <box id="a4" size="42" status="instore"/>
    <box id="a5" size="43" status="saled"/>
    
    <bag id ="b1" sive="16x20" status="instore"><numberofbook>12</numberofbook></bag>
    <bag id ="b2" sive="10x10" status="instore"><numberofbook>8</numberofbook></bag>
    <bag id ="b3" sive="16x10" status="instore"><numberofbook>10</numberofbook></bag>
    <bag id ="b4" sive="16x20" status="saled"></bag>
    <bag id ="b5" sive="16x20"><numberofbook>13</numberofbook></bag>
    
    <can id = "c1" size ="100m3" status="instore"><oil>3l</oil></can>
    <can id = "c2" size ="120m3" status="saled"><oil>4l</oil></can>
    <can id = "c3" size ="200m3" status="instore"></can>
    <can id = "c4" size ="210m3" status="saled"><oil>4l</oil></can>
    <can id = "c5" size ="220m3" status="instore"><oil>5l</oil></can>
    <can id = "c6" size ="300m3" status="saled" ><oil>13l</oil></can>

</listcontainer>
</root>
then the XSLT 2.0 stylesheet
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  
  <xsl:template match="listcontainer">
    <goods_status>
      <xsl:for-each-group select="*" group-by="@status">
        <xsl:element name="{current-grouping-key()}_goods">
          <xsl:apply-templates select="current-group()"/>
        </xsl:element>
      </xsl:for-each-group>
    </goods_status>
  </xsl:template>
  
  <xsl:template match="box[*] | bag[*] | can[*]">
    <xsl:element name="notempty_{local-name()}"/>
  </xsl:template>
  
  <xsl:template match="box[not(*)] | bag[not(*)] | can[not(*)]">
    <xsl:element name="empty_{local-name()}"/>
  </xsl:template>
  
</xsl:stylesheet>
outputs
Code:
<goods_status>
   <saled_goods>
      <notempty_box/>
      <empty_box/>
      <empty_bag/>
      <notempty_can/>
      <notempty_can/>
      <notempty_can/>
   </saled_goods>
   <instore_goods>
      <notempty_box/>
      <notempty_box/>
      <empty_box/>
      <notempty_bag/>
      <notempty_bag/>
      <notempty_bag/>
      <notempty_can/>
      <empty_can/>
      <notempty_can/>
   </instore_goods>
</goods_status>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
The Following User Says Thank You to Martin Honnen For This Useful Post:
metinhoclam (August 14th, 2010)





Similar Threads
Thread Thread Starter Forum Replies Last Post
Chap 16 pg 574: Elements not supported Elements not known tomche BOOK: Beginning ASP.NET 3.5 : in C# and VB BOOK ISBN: 978-0-470-18759-3 1 August 6th, 2009 02:48 PM
help in selecting elements spandit XSLT 1 April 9th, 2007 07:27 PM
elements with same name kfir XML 8 May 1st, 2006 07:42 AM
Selecting elements up until a certain one Frode XSLT 5 January 19th, 2006 01:22 PM
Restrict elements guozhang XML 0 April 28th, 2004 02:26 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.