Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
859 views
in Technique[技术] by (71.8m points)

xml - Perl Error while performing xslt transformation

I am trying to perform a simple xml transformation using XSLT 1.0. Here are my xml and xslt files.

XML File

<?xml version="1.0"?>
<?xml-stylesheet type="xsl" href="trans.xsl"?>
<Article>
  <Title>My Article</Title>
  <Authors>
    <Author>Mr. Foo</Author>
    <Author>Mr. Bar</Author>
  </Authors>
  <Body>This is my article text.</Body>
</Article>

XSLT File

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
  <xsl:output method="text"/>    
  <xsl:template match="/">
    Article - <xsl:value-of select="/Article/Title"/>
    Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
  </xsl:template>    
  <xsl:template match="Author">
    - <xsl:value-of select="." />
  </xsl:template>    
</xsl:stylesheet>

And here is my perl script that I am using.

use strict;
use warnings;
use Getopt::Std;
use File::Path;
use File::Spec;
use File::Basename;
use Env;
use XML::LibXSLT;
use XML::LibXML;

my %opts = ();
getopts('p:f:'\%opts);

my $xsltfile = $opts{'p'};
die "XSLT file not specified" if !defined($xsltfile);

my $xmlfile = $opts{'f'};
die "XML file not specified" if !defined($xmlfile);

# XSLT Transformation code starts here

#my $xml_parser = XML::LibXML->new();
#my $source = $xml_parser->parse_file($msgcatfile);

my $source = XML::LibXML->load_xml(location => $xmlfile);

#my $xslt_parser = XML::LibXML->new();
#my $xslt_source = $xslt_parser->parse_file($xsltfile);

my $xslt_source = XML::LibXML->load_xml(location => $xsltfile);    
my $xslt = XML::LibXSLT->new();

my $stylesheet;

eval { $stylesheet = $xslt->parse_stylesheet($xslt_source); };

if ($@)
{
    print "$@";
    die "
!******************Error in parsing the stylesheet file : $xsltfile ************************!
";
}

eval { my $results = $stylesheet->transform_file($source); };

if ($@)
{
    print "$@";
    die "
!******************Error in transforming the input xml file : $source ************************!
";
}
print $stylesheet->output_as_bytes($results);
0;

I am not sure what is going wrong but when run this perl script, I am getting following errors which I am not able decipher.

Bareword found where operator expected at trans.xslt line 2, near ""1.0" xmlns"
        (Missing operator before xmlns?)
Bareword found where operator expected at trans.xslt line 11, near "</xsl"
  (Might be a runaway multi-line // string starting on line 10)
        (Missing operator before l?)
syntax error at trans.xslt line 2, near "xsl:"
Execution of trans.xslt aborted due to compilation errors.

I could not find any similar posts (relevant to XML/XSLT) when I searched for keywords in the error message. Am I missing something obvious?

:UPDATE:

I ran my program as

perl transform.pl -p trans.xslt -f example.xml

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Somehow you are executing your XSLT file as Perl code, but there is nothing in your question to explain how. In fact, as I commented, the Perl code that you show cannot have caused the error you say it did because it won't compile

I can see a problem with the call to $stylesheet->transform_file($source), which should be either $stylesheet->transform($source) or $stylesheet->transform_file($xmlfile), but the rest of the bugs are obvious

Note also that the stylesheet attached to the XML document with the xml-stylesheet processing instruction is test.xsl, whereas your Perl code applies test.xslt. You should choose one or the other

Your call to $stylesheet->output_as_bytes($results) is better as $stylesheet->output_as_chars($results). It doesn't make any difference with pure ASCII data, but the former will produce encoded octets, which is rarely useful. Usually you just want a character string

It's best to avoid writing fancy parameter input and exception-handling code before you have the basic program working. I suggest you start from my code here instead, and use the Try::Tiny module instead of a simple eval if you must handle the errors. At present, all your handlers seem to do is supplement the exception message with a lot of stars and then die anyway, so I think you can do without them

use strict;
use warnings;

use XML::LibXSLT;

my ($xmlfile, $xsltfile) = qw/ example.xml trans.xsl /;

my $xslt = XML::LibXSLT->new;
my $stylesheet = $xslt->parse_stylesheet_file($xsltfile);
my $results    = $stylesheet->transform_file($xmlfile);

print $stylesheet->output_as_chars($results);

output

Article - My Article
Authors: 
- Mr. Foo
- Mr. Bar

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...