Replace spaces within a string value of an attribute of an XML tag

Replace spaces within a string value of an attribute of an XML tag

3
NewbieNewbie
3

    May 05, 2012#1

    Hello,

    this is my first post here. I've been using UltraEdit for quite a while but I'm only beginning scripting and I kinda struggle (don't know js either).
    However I want to give it a good shot because I think it would help me a lot with work, replacing some software I write in C#.
    I'm using Version 17.30.0.1014.

    So my problem is the following: I have a xml file that looks like that:

    Code: Select all

    <package name="TEE_TimeArithm_API" version="v1.7" date="2012-04-21">
        <initial-state name="Internal_API_Time_Arithm">
            <!--Targeted operation: FinalizeContext-->
            <scenario name="Invoke_BigIntCmpS32_op strictly lesser than shortval_size 32 bits_two negative values (ce-ef-9e)" destructive="yes">
                <req name="BIG_INT_CMP_32" />
    ...
    The node scenario may have a name attribute that contains " " (space). I need to replace them with "_".
    There are quite a lot of nodes impacted.

    The result I look for is the same file with

    Code: Select all

            <scenario name="Invoke_BigIntCmpS32_op_strictly_lesser_than_shortval_size_32_bits_two_negative_values_(ce-ef-9e)" destructive="yes">
    I've started with that code to find the first occurrence:

    Code: Select all

    var regex = "<scenario name=(.*) destructive"; //Perl regular expression to find title string
    
    // Start at the beginning of the file
    UltraEdit.activeDocument.top();
    
    // Turn on regular expressions
    UltraEdit.activeDocument.findReplace.regExp = true;
    // Find it
    UltraEdit.activeDocument.findReplace.find(regex);
    
    var reg = new RegExp(" ", "g");
    
    // Load it into a selection
    var titl = UltraEdit.activeDocument.selection;
    
    titl = titl.substring(16, titl.lastIndexOf("destructive") - 2);
    
    var reptitl = titl.replace(reg, "_");
    If I print the variable reptitl I see the job has been done.

    But then I don't know how:
    • I replace the text inside the original file
    • I perform the job on all the occurrences
    I'd appreciate any help. Thanks a lot in advance.

    6,677585
    Grand MasterGrand Master
    6,677585

      May 06, 2012#2

      I can offer two different scripts. The first script uses your idea with running a Perl regular expression search to find the string values of interest, get the found strings, replace all spaces with underscores and write the modified strings into the file.

      Code: Select all

      if (UltraEdit.document.length > 0) {  // Is at least 1 file opened?
      
         // Define working environment for the script.
         UltraEdit.insertMode();
         if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
         else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
         // Move the caret to top of the file.
         UltraEdit.activeDocument.top();
      
         // Define the parameters for the Perl regular expression search.
         UltraEdit.perlReOn();
         UltraEdit.activeDocument.findReplace.mode=0;
         UltraEdit.activeDocument.findReplace.matchCase=false;
         UltraEdit.activeDocument.findReplace.matchWord=false;
         UltraEdit.activeDocument.findReplace.regExp=true;
         UltraEdit.activeDocument.findReplace.searchDown=true;
         if (typeof(UltraEdit.activeDocument.findReplace.searchInColumn) == "boolean")
            UltraEdit.activeDocument.findReplace.searchInColumn=false;
      
         // Run in a loop the Perl regular expression search to select the string value
         // from first to next double quote and replace all spaces inside any found
         // string by an underscore. (?<=<scenario name=) is a lookbehind expression to
         // select only "..." after string <scenario name= ignoring all other strings
         // enclosed in double quotes. And .+? matches non greedy any text within the
         // double quotes after <scenario name=.
         while(UltraEdit.activeDocument.findReplace.find("(?<=<scenario name=)\".+?\"")) {
            UltraEdit.activeDocument.write(UltraEdit.activeDocument.selection.replace(/ /g,"_"));
         }
      }
      The disadvantage of above script is that it might be slow when there are many string values to modify because of many display updates with changing positions in file.

      Here is an alternate solution. A Perl regular expression Replace All executed always from top of file replaces one space after the other within the value of attribute name of tag scenario until no space found anymore in these strings.

      Code: Select all

      if (UltraEdit.document.length > 0) {  // Is at least 1 file opened?
      
         // Define working environment for the script.
         UltraEdit.insertMode();
         if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
         else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
         // Move the caret to top of the file.
         UltraEdit.activeDocument.top();
      
         // Define the parameters for the Perl regular expression replace.
         UltraEdit.perlReOn();
         UltraEdit.activeDocument.findReplace.mode=0;
         UltraEdit.activeDocument.findReplace.matchCase=false;
         UltraEdit.activeDocument.findReplace.matchWord=false;
         UltraEdit.activeDocument.findReplace.regExp=true;
         UltraEdit.activeDocument.findReplace.searchDown=true;
         if (typeof(UltraEdit.activeDocument.findReplace.searchInColumn) == "boolean")
            UltraEdit.activeDocument.findReplace.searchInColumn=false;
         UltraEdit.activeDocument.findReplace.preserveCase=false;
         UltraEdit.activeDocument.findReplace.replaceAll=true;
         UltraEdit.activeDocument.findReplace.replaceInAllOpen=false;
      
         // Run in a loop the Perl regular expression Replace All to replace all spaces
         // within string value of name attribute of scenario tag. The replace uses a
         // tagged regular expression. On every loop run one more space is replaced
         // by an underscore until all spaces in <scenario name="..." are replaced.
         while(UltraEdit.activeDocument.findReplace.replace("(<scenario name=\"[^ \"]+) ","\\1_"));
      }

      3
      NewbieNewbie
      3

        May 06, 2012#3

        Hello,

        that second script looks very impressive to me. I'll have a shot tomorrow, that's exactly what I needed :P
        Thanx.

        Next question is then: what if the attribute was not next to the tag?
        Is there anything built in (that I haven't seen yet) to parse and edit xml files?
        That's definitely what I need most with that scripting.

        Thanks again, I keep you posted.

        Nicolas

        6,677585
        Grand MasterGrand Master
        6,677585

          May 07, 2012#4

          fakedave wrote:What if the attribute was not next to the tag?
          I this case you can use only the second script because lookbehind works only with constant strings and not with expressions. In second script you have to change the regular expression.

          while(UltraEdit.activeDocument.findReplace.replace("(<scenario[^>]+?name=\"[^ \"]+) ","\\1_"));
          fakedave wrote:Is there anything built in (that I haven't seen yet) to parse and edit xml files?
          There is the special command Format - XML Convert to CR/LFs also available as scripting command. Other special UltraEdit scripting commands are not available. As you can read at JavaScript Guide there is the E4X extension since Javascript 1.6. But I don't know if this extension is available also in UltraEdit. I have never tried it because not needed for myself.

          Further there is View - Views/Lists - XML Manager. And UE v18.00 has also the feature to automatically insert closing tag after typing an opening tag.

          3
          NewbieNewbie
          3

            May 07, 2012#5

            That worked like a charm !!! That's great.
            I think I need to get up to speed with those scripts. Most important for me at the moment is to understand perl expressions because it looks very obscure now.

            Thanks again!!

            Nicolas