Tapatalk

How to replace strings in an XML in a loop from a list file?

How to replace strings in an XML in a loop from a list file?

3
NewbieNewbie
3

    Feb 11, 2014#1

    I would need some help here as I am completely new to UltraEdit. I was previously using a different text editor, but the new place I'm working at uses UltraEdit. So I have to use it to do what I need.

    I have a standard XML set of code:

    Code: Select all

       <selectionset name="XXXXXX">
          <findspec mode="all" disjoint="0">
            <conditions>
              <condition test="contains" flags="10">
                <property>
                  <name internal="LcOaSceneBaseUserName">Name</name>
                </property>
                <value>
                  <data type="wstring">XXXXXX</data>
                </value>
              </condition>
            </conditions>
            <locator>/</locator>
          </findspec>
        </selectionset>
    I have a text file with 1500+ lines. The first 2 lines of the text file are as follows:

    Code: Select all

    20-100-AC-BFW-1001
    20-150-AC-BFW-1002-38H-ET
    I want to end up with the following:

    Code: Select all

      <selectionset name="20-100-AC-BFW-1001">
          <findspec mode="all" disjoint="0">
             <conditions>
              <condition test="contains" flags="10">
                 <property>
                  <name internal="LcOaSceneBaseUserName">Name</name>
                 </property>
                <value>
                  <data type="wstring">20-100-AC-BFW-1001</data>
                 </value>
              </condition>
            </conditions>
             <locator>/</locator>
          </findspec>
        </selectionset>
       <selectionset name="20-150-AC-BFW-1002-38H-ET">
           <findspec mode="all" disjoint="0">
             <conditions>
              <condition test="contains" flags="10">
                <property>
                  <name internal="LcOaSceneBaseUserName">Name</name>
                 </property>
                <value>
                  <data type="wstring">20-150-AC-BFW-1002-38H-ET</data>
                </value>
              </condition>
             </conditions>
             <locator>/</locator>
          </findspec>
        </selectionset>
    But repeated through the 1500+ lines in my text file.

    I've tried to create a macro, but none of the functions using the XML editor are captured in the automatic macro creation. It would be the fastest way to do it. Use the XML function to copy the segment of code to the bottom, select the original segment of code, copy the (n)th line from the text file, replace in the XML file, save and repeat with a loop until it reaches the end of the text file. At least that was what I thought to try doing.

    Not being able to do that, I haven't come up with a way to create the document that I need. Any and all help would be appreciated to make this happen.

    6,688587
    Grand MasterGrand Master
    6,688587

      Feb 12, 2014#2

      Your request is a very common request and therefore there are lots of macros and scripts in the macros and scripts forums which need just a little modification to fulfill your specific requirements. Scripts are nowadays better than macros for such tasks because of access of all files without needing to switch active file and supporting variables and arrays.

      Open as first file the XML file to process. Open the file with the strings to insert into the XML file as second file.

      Create a new ANSI file (not a UTF-8 or UTF-16 file) with DOS line terminators and paste following UE script code into this new file.

      Code: Select all

      // Your request is a very common request and therefore there are lots of macros and scripts in the macros and scripts forums which need just a little modification to fulfill your specific requirements.
      
      if (UltraEdit.document.length > 0)  // Are at least 2 files opened?
      {
         // Define environment for this script.
         UltraEdit.insertMode();
         if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
         else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
      
         // Determine line terminator type of second file.
         var sLineTerm = "\r\n";
         if (UltraEdit.document[1].lineTerminator == 1) sLineTerm = "\n";
         else if (UltraEdit.document[1].lineTerminator == 2) sLineTerm = "\r";
      
         // Select everything in second file and load the lines
         // into an array of strings with each line being a string.
         UltraEdit.document[1].selectAll();
         if (UltraEdit.document[1].isSel())
         {
            var asValues = UltraEdit.document[1].selection.split(sLineTerm);
            // Remove the last string if it is an empty string
            // because content of file ends with a line termination.
            if (asValues[asValues.length-1] == "") asValues.pop();
            // Cancel the selection by moving caret to top of second file.
            UltraEdit.document[1].top();
      
            // Move caret to top of first file.
            UltraEdit.document[0].top();
      
            // Define the parameters for the replaces made on first file.
            UltraEdit.ueReOn();
            UltraEdit.document[0].findReplace.mode=0;
            UltraEdit.document[0].findReplace.matchCase=true;
            UltraEdit.document[0].findReplace.matchWord=false;
            UltraEdit.document[0].findReplace.regExp=true;
            UltraEdit.document[0].findReplace.searchDown=true;
            UltraEdit.document[0].findReplace.searchInColumn=false;
            UltraEdit.document[0].findReplace.preserveCase=false;
            UltraEdit.document[0].findReplace.replaceAll=false;
            UltraEdit.document[0].findReplace.replaceInAllOpen=false;
      
            // Run now the replaces from top to bottom of first file with using
            // the values read in from second file. Loop exits if all values
            // from second file are processed or the string to find is not
            // found anymore in first file.
            for (var nValue = 0; nValue < asValues.length; nValue++)
            {
               var sReplace = '^1' + asValues[nValue] + '^2';
               if (!UltraEdit.document[0].findReplace.replace('^(<selectionset name="^)*^(">^)', sReplace)) break;
               if (!UltraEdit.document[0].findReplace.replace('^(<data type="wstring">^)*^(</data>^)', sReplace)) break;
            }
            UltraEdit.document[0].top();
         }
      }
      
      Save the file for example as ReplaceValuesFromList.js.

      Click in menu Scripting on Run Active Script and the XML file will be updated with the data from the list file.
      Best regards from an UC/UE/UES for Windows user from Austria

      3
      NewbieNewbie
      3

        Feb 12, 2014#3

        Mofi,

        Thanks for your quick response. I tested it out, but it didn't give me exactly what I needed originally (later Mofi corrected the script). So I have one more question.

        Must I have in the XML file the correct number of lines to match what I have in the text file (1508 lines in text file X 15 lines of original code in the XML = 22620 lines required in XML)? That isn't a problem, it's just copy/pasting until I get that many lines.

        6,688587
        Grand MasterGrand Master
        6,688587

          Feb 12, 2014#4

          Sorry, I have misread what changed in the output data example and therefore made originally the wrong replaces.

          I modified the script in my previous post and now it should be really producing the expected output.

          As I wrote in the comment above the loop, if list file has only 1508 lines (= 1508 XML blocks to update), the loop exits after making the updates on the first 1508 blocks in the XML file. If there are less blocks in the XML file as data provided in the list file, the loop exits after updating the last block in the XML file.

          Of course it would be possible to add one more condition in the loop and changing the for loop to a while loop which starts from beginning of the data from the list file until all blocks in the XML file have been updated if you need that to avoid copying and pasting the data in the list file by yourself in future.

          Here is the code for such an alternate loop.

          Code: Select all

               if(asValues.length)
                {
                   // Run now the replaces from top to bottom of first file with
                   // using the values read in from second file and applied in a
                   // loop until all blocks in XML file are updated with the data.
                   var nValue = 0;
                   while(true)
                   {
                      var sReplace = '^1' + asValues[nValue] + '^2';
                      if (!UltraEdit.document[0].findReplace.replace('^(<selectionset name="^)*^(">^)', sReplace)) break;
                      if (!UltraEdit.document[0].findReplace.replace('^(<data type="wstring">^)*^(</data>^)', sReplace)) break;
                      if ((++nValue) >= asValues.length) nValue = 0;
                   }
                }
          Best regards from an UC/UE/UES for Windows user from Austria

          3
          NewbieNewbie
          3

            Feb 12, 2014#5

            Mofi,

            Yes, that time it worked exactly as I need it. Thank you again for your time and looking at this for me.

            Regards!!