http://www.perlmonks.org?node_id=1027163

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

Hello Team,

I would like to replace the text in <subfield code="0"> in datafield 650 below.

<datafield tag="650" ind1=" " ind2="7"> <subfield code="a">Sciences</subfield> <subfield code="x">Philosophie.</subfield> <subfield code="2">ram.</subfield> <subfield code="0">(OSt)16</subfield>
I have my Script down here.
use strict; use warnings; use XML::Twig; use Data::Dumper; my $xml = <<XML; <?xml version="1.0" encoding="UTF-8"?> <collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/ +standards/marcxml/schema/MARC21slim.xsd" xmlns="http://www.loc.gov/MARC21/slim"> <record> <leader>01376cam a2200349 4500</leader> <controlfield tag="001">2 </controlfield> <controlfield tag="003">OCoLC</controlfield> <controlfield tag="005">20060313170419.0</controlfield> <controlfield tag="008">690410s1963 laua b 000 0 eng </controlfield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 63022268</subfield> </datafield> <datafield tag="019" ind1=" " ind2=" "> <subfield code="a">9772597</subfield> </datafield> <datafield tag="029" ind1="1" ind2=" "> <subfield code="a">NLGGC</subfield> <subfield code="b">861755170</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)2</subfield> <subfield code="z">(OCoLC)9772597</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">DLC</subfield> <subfield code="c">DLC</subfield> <subfield code="d">OCLCQ</subfield> <subfield code="d">TSE</subfield> <subfield code="d">OCL</subfield> </datafield> <datafield tag="043" ind1=" " ind2=" "> <subfield code="a">n-us-la</subfield> </datafield> <datafield tag="049" ind1=" " ind2=" "> <subfield code="a">OCLC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">GB475.L6</subfield> <subfield code="b">M6</subfield> </datafield> <datafield tag="082" ind1=" " ind2="4"> <subfield code="a">589.3</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Morgan, James P.</subfield> <subfield code="q">(James Plummer),</subfield> <subfield code="d">1919-</subfield> <subfield code="0">(OSt)873</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Mudlumps at the mouth of South Pass, Mississippi Ri +ver;</subfield> <subfield code="b">sedimentology, paleontology, structure, origin, and + relation to deltaic processes,</subfield> <subfield code="c">by James P. Morgan, James M. Coleman and Sherwood M +. Gagliano. Including appendices by R.D. Adams ... et al..</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">Baton Rouge,</subfield> <subfield code="b">Louisiana State University Press,</subfield> <subfield code="c">1963.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">xvi, 190 p.</subfield> <subfield code="b">illus.</subfield> <subfield code="c">28 cm.</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">Louisiana State University studies.</subfield> <subfield code="p">Coastal studies series ;</subfield> <subfield code="v">no. 10.</subfield> <subfield code="0">(OSt)13</subfield> </datafield> <datafield tag="504" ind1=" " ind2=" "> <subfield code="a">Bibliography: p. 183-190.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Mud lumps</subfield> <subfield code="z">Louisiana</subfield> <subfield code="z">Mississippi River Delta.</subfield> <subfield code="0">(OSt)14</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Sediments (Geology)</subfield> <subfield code="z">Louisiana.</subfield> <subfield code="0">(OSt)15</subfield> </datafield> <datafield tag="650" ind1=" " ind2="7"> <subfield code="a">Sciences</subfield> <subfield code="x">Philosophie.</subfield> <subfield code="2">ram.</subfield> <subfield code="0">(OSt)16</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Coleman, James M.,</subfield> <subfield code="e">joint author.</subfield> <subfield code="0">(OSt)17</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Gagliano, Sherwood M.,</subfield> <subfield code="e">joint author.</subfield> <subfield code="0">(OSt)18</subfield> </datafield> <datafield tag="994" ind1=" " ind2=" "> <subfield code="a">02</subfield> <subfield code="b">OCL</subfield> </datafield> <datafield tag="945" ind1=" " ind2=" "> <subfield code="a">GB475.L6 M6</subfield> </datafield> <datafield tag="999" ind1=" " ind2=" "> <subfield code="c">1</subfield> <subfield code="d">1</subfield> </datafield> </record> </collection> XML my $twig = XML::Twig->new ( twig_roots => {href => \&editHref,}, twig_print_outside_roots => 1, ); $twig->parse ($xml); $twig->flush; sub editHref { my ($twig, $href) = @_; my $text = $href->text (); my $orig = "(OSt)16"; $text =~ s/\.$orig$/(OSt)20/; $href->set_text ($text); $href->print (); }

Replies are listed 'Best First'.
Re: Replacing a text in XML.
by toolic (Bishop) on Apr 05, 2013 at 16:26 UTC
    I can see 2 problems. Your XML does not have an element named "href". You need to change elements named "subfield". Your regex is incorrect:
    my $twig = XML::Twig->new( twig_handlers => { subfield => \&editHref, }, pretty_print => 'indented', ); $twig->parse($xml); $twig->print; sub editHref { my ( $twig, $href ) = @_; my $text = $href->text(); my $orig = "(OSt)16"; $text =~ s/\Q$orig/(OSt)20/; $href->set_text($text); }

    Or, just avoid the regex...

    sub editHref { my ( $twig, $href ) = @_; my $text = $href->text(); $href->set_text('(OSt)20') if $text eq '(OSt)16'; }

      Thanks for the reply, Also I have another question to ask, If I want to search through the same XML file for this subfield. <subfield code="0">(OSt)18</subfield> from the database how do I go by it? Thanks.
Re: Replacing a text in XML.
by choroba (Cardinal) on Apr 05, 2013 at 16:27 UTC
    You callback is never called, as there is no <href> element anywhere in your xml. You probably meant
    twig_roots => { 'subfield[@code="0"]' => \&editHref},
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ