Replacing a value in an XML document with another value taken from elsewhere in the document












-1















Script:



#!/bin/ksh

tu=$(cat /export/home/a1016169/stack.txt;)
tu1=$(echo "$tu" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/tu/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
print "n $tu1"

qc=$(cat /export/home/a1016169/stack.txt;)
qc1=$(echo "$qc" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/qc/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
print "n $qc1"

sed 's/"$qc1"/"$tu1"/' - > /export/home/a1016169/stack.txt


stack.txt file:



 <prpr name = "EM_CLIENT_VERSION" encryptionClass = "com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
<lcycl name="pu">
<prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
</lcycl>
<lcycl name="qc">
<prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
</lcycl>
<lcycl name="qa">
<prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
</lcycl>
<lcycl name="tu">
<prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
</lcycl>
<lcycl name="dv">
<prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"></prprvl>
</lcycl>
</prpr>


I'm getting an error from the last command as Can't open -.



I want to change 9999a in <lcycl name="qc"> (only under this section) to 0220a value. The value should be taken from <lcycl name="tu">.










share|improve this question





























    -1















    Script:



    #!/bin/ksh

    tu=$(cat /export/home/a1016169/stack.txt;)
    tu1=$(echo "$tu" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/tu/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
    print "n $tu1"

    qc=$(cat /export/home/a1016169/stack.txt;)
    qc1=$(echo "$qc" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/qc/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
    print "n $qc1"

    sed 's/"$qc1"/"$tu1"/' - > /export/home/a1016169/stack.txt


    stack.txt file:



     <prpr name = "EM_CLIENT_VERSION" encryptionClass = "com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
    <lcycl name="pu">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
    </lcycl>
    <lcycl name="qc">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
    </lcycl>
    <lcycl name="qa">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
    </lcycl>
    <lcycl name="tu">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
    </lcycl>
    <lcycl name="dv">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"></prprvl>
    </lcycl>
    </prpr>


    I'm getting an error from the last command as Can't open -.



    I want to change 9999a in <lcycl name="qc"> (only under this section) to 0220a value. The value should be taken from <lcycl name="tu">.










    share|improve this question



























      -1












      -1








      -1








      Script:



      #!/bin/ksh

      tu=$(cat /export/home/a1016169/stack.txt;)
      tu1=$(echo "$tu" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/tu/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
      print "n $tu1"

      qc=$(cat /export/home/a1016169/stack.txt;)
      qc1=$(echo "$qc" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/qc/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
      print "n $qc1"

      sed 's/"$qc1"/"$tu1"/' - > /export/home/a1016169/stack.txt


      stack.txt file:



       <prpr name = "EM_CLIENT_VERSION" encryptionClass = "com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
      <lcycl name="pu">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
      </lcycl>
      <lcycl name="qc">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
      </lcycl>
      <lcycl name="qa">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
      </lcycl>
      <lcycl name="tu">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
      </lcycl>
      <lcycl name="dv">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"></prprvl>
      </lcycl>
      </prpr>


      I'm getting an error from the last command as Can't open -.



      I want to change 9999a in <lcycl name="qc"> (only under this section) to 0220a value. The value should be taken from <lcycl name="tu">.










      share|improve this question
















      Script:



      #!/bin/ksh

      tu=$(cat /export/home/a1016169/stack.txt;)
      tu1=$(echo "$tu" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/tu/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
      print "n $tu1"

      qc=$(cat /export/home/a1016169/stack.txt;)
      qc1=$(echo "$qc" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/qc/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
      print "n $qc1"

      sed 's/"$qc1"/"$tu1"/' - > /export/home/a1016169/stack.txt


      stack.txt file:



       <prpr name = "EM_CLIENT_VERSION" encryptionClass = "com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
      <lcycl name="pu">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
      </lcycl>
      <lcycl name="qc">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
      </lcycl>
      <lcycl name="qa">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
      </lcycl>
      <lcycl name="tu">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
      </lcycl>
      <lcycl name="dv">
      <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"></prprvl>
      </lcycl>
      </prpr>


      I'm getting an error from the last command as Can't open -.



      I want to change 9999a in <lcycl name="qc"> (only under this section) to 0220a value. The value should be taken from <lcycl name="tu">.







      shell-script xml






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Feb 20 at 23:09









      Kusalananda

      135k17255418




      135k17255418










      asked Feb 20 at 20:51









      user334028user334028

      56




      56






















          1 Answer
          1






          active

          oldest

          votes


















          3














          Using XMLStarlet:



          $ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
          <?xml version="1.0"?>
          <prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
          <lcycl name="pu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
          </lcycl>
          <lcycl name="qc">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="qa">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
          </lcycl>
          <lcycl name="tu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="dv">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
          </lcycl>
          </prpr>


          The XPath //lcycl[@name="qc"]/prprvl would match the prprvl node that is the immediate child node of the lcycl node which has a name attribute with value qc. Here, xmlstarlet will change the prprvl node's value to 0220a regardless of what its initial value was.



          If you don't want to hard code the 0220a value, but pick it from the //lcycl[@name="tu"]/prprvl node, use



          xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' 
          -x '//lcycl[@name="tu"]/prprvl/text()' file.xml


          Redirect the output to a new file and then rename the new file to the original name.





          The equivalent thing in Perl, which will pick up file.xml from the current directory:



          #!/usr/bin/perl

          use strict;
          use warnings;

          use XML::XPath;
          use XML::XPath::XMLParser;

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

          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

          my $nodeset = $xp->find('/');

          foreach my $node ( $nodeset->get_nodelist() ) {
          print XML::XPath::XMLParser::as_string($node);
          }


          Here, if you want to pick that value from that other node, use



          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
          $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );


          instead of the other setNodeText() line.



          Redirect the output to a new file and then rename the new file to the original name.





          The error that you get is due to trying to open a file called -. GNU sed would treat - as the standard input stream, but other sed implementations (e.g. BSD sed) would see it as an ordinary filename.



          In any case, you don't give sed any data to operate on. This means that the file that you redirect to will be truncated and left empty.






          share|improve this answer


























          • not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

            – user334028
            Feb 20 at 21:06








          • 1





            @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

            – Kusalananda
            Feb 20 at 21:08











          • currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

            – user334028
            Feb 20 at 21:08






          • 1





            @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

            – Kusalananda
            Feb 20 at 21:18






          • 1





            @user334028 A added another Unix solution, this time a Perl script.

            – Kusalananda
            Feb 20 at 22:19











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501954%2freplacing-a-value-in-an-xml-document-with-another-value-taken-from-elsewhere-in%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Using XMLStarlet:



          $ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
          <?xml version="1.0"?>
          <prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
          <lcycl name="pu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
          </lcycl>
          <lcycl name="qc">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="qa">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
          </lcycl>
          <lcycl name="tu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="dv">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
          </lcycl>
          </prpr>


          The XPath //lcycl[@name="qc"]/prprvl would match the prprvl node that is the immediate child node of the lcycl node which has a name attribute with value qc. Here, xmlstarlet will change the prprvl node's value to 0220a regardless of what its initial value was.



          If you don't want to hard code the 0220a value, but pick it from the //lcycl[@name="tu"]/prprvl node, use



          xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' 
          -x '//lcycl[@name="tu"]/prprvl/text()' file.xml


          Redirect the output to a new file and then rename the new file to the original name.





          The equivalent thing in Perl, which will pick up file.xml from the current directory:



          #!/usr/bin/perl

          use strict;
          use warnings;

          use XML::XPath;
          use XML::XPath::XMLParser;

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

          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

          my $nodeset = $xp->find('/');

          foreach my $node ( $nodeset->get_nodelist() ) {
          print XML::XPath::XMLParser::as_string($node);
          }


          Here, if you want to pick that value from that other node, use



          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
          $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );


          instead of the other setNodeText() line.



          Redirect the output to a new file and then rename the new file to the original name.





          The error that you get is due to trying to open a file called -. GNU sed would treat - as the standard input stream, but other sed implementations (e.g. BSD sed) would see it as an ordinary filename.



          In any case, you don't give sed any data to operate on. This means that the file that you redirect to will be truncated and left empty.






          share|improve this answer


























          • not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

            – user334028
            Feb 20 at 21:06








          • 1





            @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

            – Kusalananda
            Feb 20 at 21:08











          • currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

            – user334028
            Feb 20 at 21:08






          • 1





            @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

            – Kusalananda
            Feb 20 at 21:18






          • 1





            @user334028 A added another Unix solution, this time a Perl script.

            – Kusalananda
            Feb 20 at 22:19
















          3














          Using XMLStarlet:



          $ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
          <?xml version="1.0"?>
          <prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
          <lcycl name="pu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
          </lcycl>
          <lcycl name="qc">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="qa">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
          </lcycl>
          <lcycl name="tu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="dv">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
          </lcycl>
          </prpr>


          The XPath //lcycl[@name="qc"]/prprvl would match the prprvl node that is the immediate child node of the lcycl node which has a name attribute with value qc. Here, xmlstarlet will change the prprvl node's value to 0220a regardless of what its initial value was.



          If you don't want to hard code the 0220a value, but pick it from the //lcycl[@name="tu"]/prprvl node, use



          xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' 
          -x '//lcycl[@name="tu"]/prprvl/text()' file.xml


          Redirect the output to a new file and then rename the new file to the original name.





          The equivalent thing in Perl, which will pick up file.xml from the current directory:



          #!/usr/bin/perl

          use strict;
          use warnings;

          use XML::XPath;
          use XML::XPath::XMLParser;

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

          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

          my $nodeset = $xp->find('/');

          foreach my $node ( $nodeset->get_nodelist() ) {
          print XML::XPath::XMLParser::as_string($node);
          }


          Here, if you want to pick that value from that other node, use



          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
          $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );


          instead of the other setNodeText() line.



          Redirect the output to a new file and then rename the new file to the original name.





          The error that you get is due to trying to open a file called -. GNU sed would treat - as the standard input stream, but other sed implementations (e.g. BSD sed) would see it as an ordinary filename.



          In any case, you don't give sed any data to operate on. This means that the file that you redirect to will be truncated and left empty.






          share|improve this answer


























          • not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

            – user334028
            Feb 20 at 21:06








          • 1





            @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

            – Kusalananda
            Feb 20 at 21:08











          • currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

            – user334028
            Feb 20 at 21:08






          • 1





            @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

            – Kusalananda
            Feb 20 at 21:18






          • 1





            @user334028 A added another Unix solution, this time a Perl script.

            – Kusalananda
            Feb 20 at 22:19














          3












          3








          3







          Using XMLStarlet:



          $ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
          <?xml version="1.0"?>
          <prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
          <lcycl name="pu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
          </lcycl>
          <lcycl name="qc">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="qa">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
          </lcycl>
          <lcycl name="tu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="dv">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
          </lcycl>
          </prpr>


          The XPath //lcycl[@name="qc"]/prprvl would match the prprvl node that is the immediate child node of the lcycl node which has a name attribute with value qc. Here, xmlstarlet will change the prprvl node's value to 0220a regardless of what its initial value was.



          If you don't want to hard code the 0220a value, but pick it from the //lcycl[@name="tu"]/prprvl node, use



          xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' 
          -x '//lcycl[@name="tu"]/prprvl/text()' file.xml


          Redirect the output to a new file and then rename the new file to the original name.





          The equivalent thing in Perl, which will pick up file.xml from the current directory:



          #!/usr/bin/perl

          use strict;
          use warnings;

          use XML::XPath;
          use XML::XPath::XMLParser;

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

          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

          my $nodeset = $xp->find('/');

          foreach my $node ( $nodeset->get_nodelist() ) {
          print XML::XPath::XMLParser::as_string($node);
          }


          Here, if you want to pick that value from that other node, use



          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
          $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );


          instead of the other setNodeText() line.



          Redirect the output to a new file and then rename the new file to the original name.





          The error that you get is due to trying to open a file called -. GNU sed would treat - as the standard input stream, but other sed implementations (e.g. BSD sed) would see it as an ordinary filename.



          In any case, you don't give sed any data to operate on. This means that the file that you redirect to will be truncated and left empty.






          share|improve this answer















          Using XMLStarlet:



          $ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
          <?xml version="1.0"?>
          <prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
          <lcycl name="pu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
          </lcycl>
          <lcycl name="qc">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="qa">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
          </lcycl>
          <lcycl name="tu">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
          </lcycl>
          <lcycl name="dv">
          <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
          </lcycl>
          </prpr>


          The XPath //lcycl[@name="qc"]/prprvl would match the prprvl node that is the immediate child node of the lcycl node which has a name attribute with value qc. Here, xmlstarlet will change the prprvl node's value to 0220a regardless of what its initial value was.



          If you don't want to hard code the 0220a value, but pick it from the //lcycl[@name="tu"]/prprvl node, use



          xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' 
          -x '//lcycl[@name="tu"]/prprvl/text()' file.xml


          Redirect the output to a new file and then rename the new file to the original name.





          The equivalent thing in Perl, which will pick up file.xml from the current directory:



          #!/usr/bin/perl

          use strict;
          use warnings;

          use XML::XPath;
          use XML::XPath::XMLParser;

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

          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

          my $nodeset = $xp->find('/');

          foreach my $node ( $nodeset->get_nodelist() ) {
          print XML::XPath::XMLParser::as_string($node);
          }


          Here, if you want to pick that value from that other node, use



          $xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
          $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );


          instead of the other setNodeText() line.



          Redirect the output to a new file and then rename the new file to the original name.





          The error that you get is due to trying to open a file called -. GNU sed would treat - as the standard input stream, but other sed implementations (e.g. BSD sed) would see it as an ordinary filename.



          In any case, you don't give sed any data to operate on. This means that the file that you redirect to will be truncated and left empty.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Feb 21 at 19:03

























          answered Feb 20 at 21:04









          KusalanandaKusalananda

          135k17255418




          135k17255418













          • not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

            – user334028
            Feb 20 at 21:06








          • 1





            @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

            – Kusalananda
            Feb 20 at 21:08











          • currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

            – user334028
            Feb 20 at 21:08






          • 1





            @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

            – Kusalananda
            Feb 20 at 21:18






          • 1





            @user334028 A added another Unix solution, this time a Perl script.

            – Kusalananda
            Feb 20 at 22:19



















          • not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

            – user334028
            Feb 20 at 21:06








          • 1





            @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

            – Kusalananda
            Feb 20 at 21:08











          • currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

            – user334028
            Feb 20 at 21:08






          • 1





            @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

            – Kusalananda
            Feb 20 at 21:18






          • 1





            @user334028 A added another Unix solution, this time a Perl script.

            – Kusalananda
            Feb 20 at 22:19

















          not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

          – user334028
          Feb 20 at 21:06







          not useful. I want the code to be written in unix and that code will pull the data from xml file and replace it

          – user334028
          Feb 20 at 21:06






          1




          1





          @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

          – Kusalananda
          Feb 20 at 21:08





          @user334028 I'm writing and testing this on a Unix system. OpenBSD to be precise.

          – Kusalananda
          Feb 20 at 21:08













          currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

          – user334028
          Feb 20 at 21:08





          currently my script is able to store those data's in variable tu1 and qc1 but note able to replace it

          – user334028
          Feb 20 at 21:08




          1




          1





          @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

          – Kusalananda
          Feb 20 at 21:18





          @user334028 A variant of Unix. Listen, and this goes for your other XML parsing questions too... The only tool in your toolbox is a chainsaw. I'm asking you to go out and buy a fruit knife to peel this apple. A chainsaw will make a mess of it.

          – Kusalananda
          Feb 20 at 21:18




          1




          1





          @user334028 A added another Unix solution, this time a Perl script.

          – Kusalananda
          Feb 20 at 22:19





          @user334028 A added another Unix solution, this time a Perl script.

          – Kusalananda
          Feb 20 at 22:19


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Unix & Linux Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501954%2freplacing-a-value-in-an-xml-document-with-another-value-taken-from-elsewhere-in%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?