3

i need help in getting the below output from shops.xml file( where incity="yes" and type="Botique" ) by using xsl . As i am new to xslt , so any help would be highly appreciated.

shops.xml:

<shops> <shop incity="yes" onlineorder="yes"> <type>Botique</type> <address> <streetno>23</streetno> <streetname>collins</streetname> <suburb>Melbourne</suburb> </address> </shop> <shop incity="yes" onlineorder="yes"> <type>Botique</type> <address> <streetno>25</streetno> <streetname>little collins</streetname> <suburb>Melbourne</suburb> </address> </shop> <shop incity="no" onlineorder="yes"> <type>Tailoring</type> <address> <streetno>2</streetno> <streetname>cosmos street</streetname> <suburb>Glenroy</suburb> </address> </shop> </shops> 

output:

<shops> <shop onlineorder="yes"> <type>Botique</type> <address> 23 collins,Melbourne </address> </shop> <shop onlineorder="yes"> <type>Botique</type> <address> 25 little collins, Melbourne </address> </shop> </shops> 

shop.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="shop[@incity='no']" /> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> 

shop.php

<?php $xmlDoc = new DOMDocument('1.0'); $xmlDoc->formatOutput = true; $xmlDoc->load("shops.xml"); $xslDoc = new DomDocument; $xslDoc->load("shop.xsl"); $proc = new XSLTProcessor; $proc->importStyleSheet($xslDoc); $strxml= $proc->transformToXML($xmlDoc); echo ($strxml); ?> 
8
  • What code have you written so far? Where did you get stuck? There are some good tutorials out there. E.g. w3schools.com/xsl Commented May 9, 2011 at 21:03
  • @James above is my xsl, but it shows the output without tags and also not showing the attribute onlineorder="yes" Commented May 9, 2011 at 21:16
  • OK - can you include the XSL you're using too please? Commented May 9, 2011 at 21:22
  • @James: reformatted the XSL paragraph. I didn't have the indent. Commented May 9, 2011 at 21:33
  • @James its now showing xsl file Commented May 9, 2011 at 21:46

3 Answers 3

1

Here's something to start with:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="shops"> <xsl:element name="shops"> <xsl:for-each select="shop"> <xsl:if test="@incity='yes'"> <xsl:if test="type='Botique'"> <xsl:element name="shop"> <xsl:attribute name="onlineorder"> <xsl:value-of select="@onlineorder"/> </xsl:attribute> <xsl:element name="type"> <xsl:value-of select="type"/> </xsl:element> <xsl:element name="address"> <xsl:value-of select="address/streetno"/> <xsl:text> </xsl:text> <xsl:value-of select="address/streetname"/> <xsl:text>, </xsl:text> <xsl:value-of select="address/suburb"/> </xsl:element> </xsl:element> </xsl:if> </xsl:if> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet> 

Output:

<?xml version="1.0"?> <shops> <shop onlineorder="yes"> <type>Botique</type> <address>23 collins, Melbourne</address> </shop> <shop onlineorder="yes"> <type>Botique</type> <address>25 little collins, Melbourne</address> </shop> </shops> 
Sign up to request clarification or add additional context in comments.

9 Comments

@sara, works fine for me. I ran it with your PHP code in PHP version 5.2.14. What kind of errors are you getting?
@mizo Warning: DOMDocument::load() [function.DOMDocument-load]: attributes construct error in shopping/shop.xsl, line: 2 in shopping/shop.php on line 6 Warning: DOMDocument::load() [function.DOMDocument-load]: Namespace prefix xsl on stylesheet is not defined in shopping/shop.xsl, line: 2 in shopping/shop.php on line 6
@mizo Warning: DOMDocument::load() [function.DOMDocument-load]: Couldn't find end of Start Tag stylesheet line 2 in shopping/shop.xsl, line: 2 in shopping/shop.php on line 6 Warning: DOMDocument::load() [function.DOMDocument-load]: Extra content at the end of the document in shopping/shop.xsl, line: 2 in shopping/shop.php on line 6 Warning: XSLTProcessor::importStylesheet() [function.XSLTProcessor-importStylesheet]: compilation error in shopping/shop.php on line 8
@mizo Warning: XSLTProcessor::importStylesheet() [function.XSLTProcessor-importStylesheet]: xsltParseStylesheetProcess : empty stylesheet in shopping/shop.php on line 8 Warning: XSLTProcessor::transformToXml() [function.XSLTProcessor-transformToXml]: No stylesheet associated to this object in shopping/shop.php on line 9
@sara, It looks like the opening <xsl:stylesheet> tag is somehow broken (it can't find the trailing >). Make sure the code stays intact when you paste it into your shop.xsl.
|
0

This is among the shortest possible transformations that is also one of the simplest and completely "in the spirit of XSLT":

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="address"> <address> <xsl:value-of select= "concat(streetno, ' ', streetname, ', ', suburb)"/> </address> </xsl:template> <xsl:template match= "@incity | shop[not(@incity='yes' and type='Botique')]"/> </xsl:stylesheet> 

when applied on the provided XML document:

<shops> <shop incity="yes" onlineorder="yes"> <type>Botique</type> <address> <streetno>23</streetno> <streetname>collins</streetname> <suburb>Melbourne</suburb> </address> </shop> <shop incity="yes" onlineorder="yes"> <type>Botique</type> <address> <streetno>25</streetno> <streetname>little collins</streetname> <suburb>Melbourne</suburb> </address> </shop> <shop incity="no" onlineorder="yes"> <type>Tailoring</type> <address> <streetno>2</streetno> <streetname>cosmos street</streetname> <suburb>Glenroy</suburb> </address> </shop> </shops> 

the wanted, correct result is produced:

<shops> <shop onlineorder="yes"> <type>Botique</type> <address>23 collins, Melbourne</address> </shop> <shop onlineorder="yes"> <type>Botique</type> <address>25 little collins, Melbourne</address> </shop> </shops> 

Do note:

  1. Overriding of the "identity template" -- the most fundamental and powerful XSLT design pattern.

  2. Pattern matching and absolutely no conditional XSLT instructions.

3 Comments

Can you explaing why are you using @incity | shop[not(@incity='yes' and type='Botique')]? Is not shop[not(@incity='yes' and type='Botique')] enough?
@empo: The final output should not contain any incity attributes and this template is "deleting" them. This is something that even your updated solution has missed doing. :)
I see. Thanks. Anyway the humble solution I've proposed does not eliminate incity as it prevents selection of it.
0

A much simpler XSL than anyone's IMO =p is the following, very readable, very simple:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <shops> <xsl:for-each select="shops/shop[@incity!='no']"> <xsl:element name="shop"> <xsl:attribute name="onlineorder"><xsl:value-of select="@onlineorder" /></xsl:attribute> <type><xsl:value-of select="type" /></type> <address> <xsl:value-of select="address/streetno" /> <xsl:text> </xsl:text> <xsl:value-of select="address/streetname" /> <xsl:text>, </xsl:text> <xsl:value-of select="address/suburb" /> </address> </xsl:element> </xsl:for-each> </shops> </xsl:template> </xsl:stylesheet> 

It's simple, because it's basically HTML. Only attributes are different like this, so you need xsl:element[name] and xsl:attribute[name].

edit
See XML, XSL and PHP source: http://hotblocks.nl/tests/xsl(t).php?source

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.