http://qs321.pair.com?node_id=238962

jptxs has asked for the wisdom of the Perl Monks concerning the following question:

I've RTFMed and STFW for hours now. What started out as a silly distraction while on vacation has now driven me close to insane. I downloaded a tutorial about XML/XSLT/XPath to play with while on vacation from work. It had me use JEdit to do stuff, but I figgered I'd try the same exercise in perl. So after a very long wait having typed perl -MCPAN -e 'install Bundle::XML' I set out to use XML::XSLT to do the job. My first crack at the code was straight off the man page (current is more complex). What that code did (and continues to do) was simply print out the HTML from my xsl file with no content. It appears that it simply ignores the contents of the xml file. The code I wrote first is long gone. I have copy and pasted five different things off the web (some straight from tutorials) that are supposed to work and seem to simply not work for me (aside from printing empty HTML tables). The code below has some wacky stuff in it I've put in to help me see what's happening, too.

I'm absolutely stumped. I'm running this on Debian(Woody) with perl 5.6.1 and XML::XSLT .40. The xsl and xml(wsdl) files are from the tutorial this started with and work as is when I use JEdit's XSLT processor. I knew XML::XSLT was not a 1.0 module when I started out, but I've now found SO many people doing exactly this with no issues I can't believe it just doesn't work. *sigh* Any help appreciated.

the perl:

#!/usr/bin/perl -w use strict; use XML::XSLT; my $xslfile = 'soap.xsl'; my $xmlfile = 'query.wsdl'; #my $parser = XML::XSLT->new (SOURCE => $xslfile); #print $parser->serve (SOURCE => $xmlfile); my $xslt = XML::XSLT->new ($xslfile, warnings => 1); open ( XML, "$xmlfile" ) or die "$! -- $?\n"; my $stuff = join "", <XML>; close(XML); print "$stuff\n"; $xslt->transform ($stuff); print "Content-type: text/html\n\n"; print $xslt->toString; $xslt->dispose;

the xsl:

<?xml version="1.0" encoding="UTF-8"?> <!-- Soap.xsl by Ammai.com. WSDL Analyzer for SOAP RPC Web + Services. January 2003. --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/T +ransform"> <xsl:template match="/"> <html> <head> <style type="text/css"> th { background: #FFD7C1; } td { background: #FAF0E6; } </style> <title>WSDL Analyzer</title> </head> <body> <table border="1"> <tr> <th><xsl:value-of select="//*[local-name()='se +rvice']/@name"/></th> </tr> <tr> <td>Endpoint: <i><xsl:value-of select="//*[loc +al-name()='service']/*[local-name()='port']/*[local-name()='address'] +/@location"/></i></td> </tr> <tr> <td>Description: <i><xsl:value-of select="//*[ +local-name()='service']/*[local-name()='documentation']"/></i></td> </tr> </table> <br/> <table border="1"> <tr> <th>Operations</th> </tr> <tr> <td><xsl:apply-templates select="//*[local-name()= +'portType']"/></td> </tr> </table> <xsl:for-each select="//*[local-name()='portType']/*[local-name()='ope +ration']"> <br/> <table border="1"> <tr> <th><xsl:value-of select="@name"/></th> </tr> <tr> <td> <i><u>Request:</u></i><br/> <xsl:call-template name="request"> <xsl:with-param name="input" select="./*[local +-name()='input']/@message"/> </xsl:call-template> <i><u>Response:</u></i><br/> <xsl:call-template name="response"> <xsl:with-param name="output" select="./*[loca +l-name()='output']/@message"/> </xsl:call-template> </td> </tr> </table> </xsl:for-each> </body> </html> </xsl:template> <xsl:template match="//*[local-name()='portType']"> <xsl:for-each select="./*[local-name()='operation']"> <xsl:value-of select="@name"/> <br/> </xsl:for-each> </xsl:template> <xsl:template name="request"> <xsl:param name="input"/> <xsl:for-each select="//*[local-name()='message'][contains($input, @n +ame)]/*[local-name()='part']"> <xsl:value-of select="@name"/> <xsl:text> : </xsl:text> <xsl:value-of select="@type"/> <br/> </xsl:for-each> </xsl:template> <xsl:template name="response"> <xsl:param name="output"/> <xsl:for-each select="//*[local-name()='message'][contains($output, @n +ame)]/*[local-name()='part']"> <xsl:value-of select="@name"/> <xsl:text> : </xsl:text> <xsl:value-of select="@type"/> <br/> </xsl:for-each> </xsl:template> </xsl:stylesheet>

the xml:

<?xml version="1.0" encoding="UTF-8"?> <definitions name="XMethodsQuery" targetNamespace="http://www.xmethods +.net/interfaces/query.wsdl" xmlns:tns="http://www.xmethods.net/interf +aces/query.wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" x +mlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://sch +emas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.o +rg/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="ht +tp://www.xmethods.net/interfaces/query.xsd" targetNamespace="http://w +ww.xmethods.net/interfaces/query.xsd"> <complexType name="ServiceSummary"> <sequence> <element name="name" nillable="true" type="xsd:str +ing"/> <element name="id" nillable="true" type="xsd:strin +g"/> <element name="shortDescription" nillable="true" t +ype="xsd:string"/> <element name="wsdlURL" nillable="true" type="xsd: +string"/> <element name="publisherID" nillable="true" type=" +xsd:string"/> </sequence> </complexType> <complexType name="ArrayOfServiceSummary"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayT +ype="tns:ServiceSummary[]"/> </restriction> </complexContent> </complexType> <complexType name="IDNamePair"> <sequence> <element name="id" nillable="true" type="xsd:strin +g"/> <element name="name" nillable="true" type="xsd:str +ing"/> </sequence> </complexType> <complexType name="ArrayOfIDNamePair"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayT +ype="tns:IDNamePair[]"/> </restriction> </complexContent> </complexType> <complexType name="ServiceDetail"> <sequence> <element name="name" nillable="true" type="xsd:str +ing"/> <element name="id" nillable="true" type="xsd:strin +g"/> <element name="shortDescription" nillable="true" t +ype="xsd:string"/> <element name="description" nillable="true" type=" +xsd:string"/> <element name="implementationID" nillable="true" t +ype="xsd:string"/> <element name="email" nillable="true" type="xsd:st +ring"/> <element name="wsdlURL" nillable="true" type="xsd: +string"/> <element name="infoURL" nillable="true" type="xsd: +string"/> <element name="discussionURL" nillable="true" type +="xsd:string"/> <element name="notes" nillable="true" type="xsd:st +ring"/> <element name="tmodelID" nillable="true" type="xsd +:string"/> <element name="publisherID" nillable="true" type=" +xsd:string"/> <element name="uuid" nillable="true" type="xsd:str +ing"/> </sequence> </complexType> </schema> </types> <message name="getServiceSummariesByPublisher0SoapIn"> <part name="publisherID" type="xsd:string"/> </message> <message name="getServiceSummariesByPublisher0SoapOut"> <part name="Result" xmlns:ns1="http://www.xmethods.net/interfa +ces/query.xsd" type="ns1:ArrayOfServiceSummary"/> </message> <message name="getAllServiceSummaries1SoapIn"/> <message name="getAllServiceSummaries1SoapOut"> <part name="Result" xmlns:ns1="http://www.xmethods.net/interfa +ces/query.xsd" type="ns1:ArrayOfServiceSummary"/> </message> <message name="getAllServiceNames2SoapIn"/> <message name="getAllServiceNames2SoapOut"> <part name="Result" xmlns:ns1="http://www.xmethods.net/interfa +ces/query.xsd" type="ns1:ArrayOfIDNamePair"/> </message> <message name="getServiceNamesByPublisher3SoapIn"> <part name="publisherID" type="xsd:string"/> </message> <message name="getServiceNamesByPublisher3SoapOut"> <part name="Result" xmlns:ns1="http://www.xmethods.net/interfa +ces/query.xsd" type="ns1:ArrayOfIDNamePair"/> </message> <message name="getServiceDetail4SoapIn"> <part name="id" type="xsd:string"/> </message> <message name="getServiceDetail4SoapOut"> <part name="Result" xmlns:ns1="http://www.xmethods.net/interfa +ces/query.xsd" type="ns1:ServiceDetail"/> </message> <portType name="XMethodsQuerySoapPortType"> <operation name="getServiceSummariesByPublisher" parameterOrde +r="publisherID"> <input name="getServiceSummariesByPublisher0SoapIn" messag +e="tns:getServiceSummariesByPublisher0SoapIn"/> <output name="getServiceSummariesByPublisher0SoapOut" mess +age="tns:getServiceSummariesByPublisher0SoapOut"/> </operation> <operation name="getAllServiceSummaries" parameterOrder=""> <input name="getAllServiceSummaries1SoapIn" message="tns:g +etAllServiceSummaries1SoapIn"/> <output name="getAllServiceSummaries1SoapOut" message="tns +:getAllServiceSummaries1SoapOut"/> </operation> <operation name="getAllServiceNames" parameterOrder=""> <input name="getAllServiceNames2SoapIn" message="tns:getAl +lServiceNames2SoapIn"/> <output name="getAllServiceNames2SoapOut" message="tns:get +AllServiceNames2SoapOut"/> </operation> <operation name="getServiceNamesByPublisher" parameterOrder="p +ublisherID"> <input name="getServiceNamesByPublisher3SoapIn" message="t +ns:getServiceNamesByPublisher3SoapIn"/> <output name="getServiceNamesByPublisher3SoapOut" message= +"tns:getServiceNamesByPublisher3SoapOut"/> </operation> <operation name="getServiceDetail" parameterOrder="id"> <input name="getServiceDetail4SoapIn" message="tns:getServ +iceDetail4SoapIn"/> <output name="getServiceDetail4SoapOut" message="tns:getSe +rviceDetail4SoapOut"/> </operation> </portType> <binding name="XMethodsQuerySoap" type="tns:XMethodsQuerySoapPortT +ype"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.or +g/soap/http"/> <operation name="getServiceSummariesByPublisher"> <soap:operation soapAction="" style="rpc"/> <input name="getServiceSummariesByPublisher0SoapIn"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </input> <output name="getServiceSummariesByPublisher0SoapOut"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </output> </operation> <operation name="getAllServiceSummaries"> <soap:operation soapAction="" style="rpc"/> <input name="getAllServiceSummaries1SoapIn"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </input> <output name="getAllServiceSummaries1SoapOut"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </output> </operation> <operation name="getAllServiceNames"> <soap:operation soapAction="" style="rpc"/> <input name="getAllServiceNames2SoapIn"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </input> <output name="getAllServiceNames2SoapOut"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </output> </operation> <operation name="getServiceNamesByPublisher"> <soap:operation soapAction="" style="rpc"/> <input name="getServiceNamesByPublisher3SoapIn"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </input> <output name="getServiceNamesByPublisher3SoapOut"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </output> </operation> <operation name="getServiceDetail"> <soap:operation soapAction="" style="rpc"/> <input name="getServiceDetail4SoapIn"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </input> <output name="getServiceDetail4SoapOut"> <soap:body use="encoded" namespace="http://www.xmethod +s.net/interfaces/query" encodingStyle="http://schemas.xmlsoap.org/soa +p/encoding/"/> </output> </operation> </binding> <service name="XMethodsQuery"> <documentation>XMethods query service</documentation> <port name="XMethodsQuerySoap" binding="tns:XMethodsQuerySoap" +> <soap:address location="http://www.xmethods.net/interfaces +/query"/> </port> </service> </definitions>
We speak the way we breathe. --Fugazi

update (broquaint): added <readmore>