Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I need to change some xml data, and I'm stuck trying to identify the node to modify, so hoping someone can dispel my ignorance.

This is a sample of the xml data file ('n4000-small.xml'); the real data has many matrix elements, not just two, and has siblings of the vm elements:
<formation name="stoneridge" version="1.6"> <block> <matrix> <vm type="sns"> <release version="8.5.e"> <supported> <fixed>123.1106</fixed> </supported> </release> </vm> <vm type="br"> <release version="7.2.2"> </release> </vm> </matrix> <matrix> <vm type="sns"> <release version="4.1.e"> <supported> <min>124.1306</min> <max>124.1500</max> </supported> </release> </vm> <vm type="br"> <release version="7.2.1"> </release> </vm> </matrix> </block> </formation>
I need to locate the 'matrix' node which has a 'vm' node of 'type="br"' with a specific 'release version' attribute value, then change that matrix's 'vm type="sns"' values (more on that below). I can't figure out what's wrong with my code:
use strict; use warnings; use XML::LibXML; my $file = 'n4000-small.xml'; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($file); # THIS WORKS - but it's finding the vm node not the matrix node foreach my $vm ($doc->findnodes('//vm[@type=\'br\']')) { print "br ", $vm->findvalue("./release/\@version"), "\n"; if ( '7.2.1' eq $vm->findvalue("./release/\@version")) { print "found 7.2.2\n" } } # this also works, finding the "br" vm with the right version, but I t +hink I need the matrix, to identify the "sns" vm my @wanted_vm = ($doc->findnodes('//vm[@type=\'br\' and ./release/@ve +rsion=\'7.2.1\']')); if( @wanted_vm ) { print "found br ", $wanted_vm[0]->findvalue('./release/@version'), + "\n"; } # this gets the 'br' matrices, but why doesn't it get the vm attribute +s? foreach my $matrix ($doc->findnodes( '//matrix/vm[@type=\'br\']' )) { if( $matrix ) { #print "matrix:", $matrix->toString(), "\n"; print "vm release version:", $matrix->findvalue('./vm/release/ +@version'), "\n"; my $vm_type = $matrix->findvalue('./vm/@type'); print "vm type:'" . $vm_type . "'" . "\n"; } }

Given that 'matrix' is parent of 'vm', can some kind, wiser monk please say why xpath './release/@version' of a vm node works, but './vm/release/@version' xpath from a matrix node does not? (I'm not certain this is the right terminology, but hope it's understandable.)

I haven't got as far as changing the "sns" vm's data yet. There will be two things to do: (i) change the value of the sns vm's 'release version' attribute; and (ii) either change the '//supported/fixed' element's text, or if there are '//supported/max' and '//supported/min' elements they must be removed and replaced by a '//supported/fixed' element with given text. Any gestures in those directions (especially on how to add the 'fixed' element) will also be very helpful and much appreciated.


In reply to xpath problem using XML::LibXML by anadem

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-23 15:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found