3

I am trying to extract the value of two particular attributes from an XML file, whose structure is below;

<environment>
    <applications>
       <application1>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applicaitons> 
</environment>

I want to be able to read the value of the attribute "host" and "port".

I've tried with the foillowing piece of code but this doesn't work for me.

#!/usr/local/bin/perl -w

use XML::XPath;

my $file = "configuration.xml";
my $xp = XML::XPath->new(filename => $file);

my $hname = $xp->find('/environment/applications/application1/app-config/server/@host');
my $pnumber = $xp->find('/environment/applications/application1/app-config/server/@port');


print $hname;

But this does not return any output whatsoever when I run this command.

Thanks in advance

1
  • 6
    I just want to say that you're a breath of fresh air. Thank you for parsing XML with an XML parser instead of using a regular expression! Commented Mar 25, 2011 at 16:40

4 Answers 4

4

Your XML is invalid! Fix it and it works fine.

$ perl test.pl
boxA
Sign up to request clarification or add additional context in comments.

1 Comment

Correct your applications tag as well as close the application1 tag.
4

Always, always start your perl scripts with;

use strict;

And while debugging, also do this;

use warnings;

That will show you that your XML is malformed to start with.

Fix your XML and it will work!

2 Comments

Actually it always displays the error, even when warnings/strict are not set.
I did miss the -w switch in the shebang line, fair cop. I stand by my use strict comment though ;-)
2

</applicaitons> should be spelled as </applications> Replace that in your XML document. The source is fine.

2 Comments

hahaha. So it seems my xpath was wrong and not the XML itself. Spotted a difference between an underscore and dash. Thanks for your help everyone! ;)
In the question you have asked, your XML IS wrong and when fixed, your existing XPath is fine. Either way, glad you're sorted.
0

Use XML:Simple. Its, well, simple.

Trying the following code:

use strict;
use warnings;
use XML::Simple;
my $xml = XMLin( <<XML );
<environment>
    <applications>
       <application1>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applicaitons> 
</environment>
XML
print $xml->{"applications"}{"app-config"}{"server"}{"host"} . "\n";
print $xml->{"applications"}{"app-config"}{"server"}{"port"} . "\n";

on your XML snippet, you'll get back an error such as:

mismatched tag at line 7, column 9, byte 159 at C:/Perl64/lib/XML/Parser.pm line 187

since its telling me there's a mismatched tag, I start examining the XML until I work out the malformed issues so I work on the XML errors until I come up with:

use strict;
use warnings;
use XML::Simple;
my $xml = XMLin( <<XML );
<environment>
    <applications>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applications> 
</environment>
XML
print $xml->{"applications"}{"app-config"}{"server"}{"host"} . "\n";
print $xml->{"applications"}{"app-config"}{"server"}{"port"} . "\n";

And now the program yields the expected:

boxA
1234

As you can see, it helped me quickly discover the source of the error and with no extra configuration XML::Simple made a very natural mapping to the perl hashes that we all love so well :-) ... simple.

4 Comments

It is for simple XML (and most XML is not simple enough for it)
OK, prompted by down votes I elaborate. I don't disagree with @David, but XML::Simple works fine for a lot of XML and if you need to you can start twiddling the options and work with even more XML. If you are looking to scale and or work with some really complex XML it may be time to move to a different module. But, look how easy it is in this case!
I suspect the downvotes are because switching XML module doesn't solve the problem (which is that the XML is malformed).
OK, I see your point, but had the OP began with XML::Simple he would have got proper error messages to help him solve his own problem. Working with this module would have saved some heart ache, and a post to stack overflow. I let my answer stand so maybe it will help others.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.