p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   XSLT (http://p2p.wrox.com/forumdisplay.php?f=86)
-   -   How to check whether an elements contains another elements or not? (http://p2p.wrox.com/showthread.php?t=80507)

metinhoclam August 14th, 2010 06:14 AM

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?

mhkay August 14th, 2010 06:21 AM

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>


metinhoclam August 14th, 2010 09:49 AM

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>


Martin Honnen August 14th, 2010 09:56 AM

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

metinhoclam August 14th, 2010 09:59 AM

altova spy
 
Dear Mr.mhkay
I'm using altova spy and I declare with xslt version 2.0

Martin Honnen August 14th, 2010 10:11 AM

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>



All times are GMT -4. The time now is 12:05 AM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.