Tapatalk

Fetch and modify content of xml node

Fetch and modify content of xml node

3

PostJul 18, 2025#1

Hello, 

I have a large XML file (150 MB) containing nested XML nodes. Some of the nodes contain coordinates. Those have to be compared to a fixed value and changed if the coordinates exceed the value (trigger). The nodes in question are:

Code: Select all

<Position>1114.25 0 1198.6755</Position>
<Position>1214.25 0 1034</Position>
<Position>200.455 1200.35 111.55</Position>
<Position>1152 65.33 1179.76</Position>
The three numbers in the node can be integer, float or 0. The first and third value have to be compared.

The written script does not produce any error but it does not change the values. To see whether I get an output I put "new" in front of the new XML node.

Code: Select all

UltraEdit.insertMode();
UltraEdit.perlReOn();
UltraEdit.activeDocument.top();
UltraEdit.activeDocument.findReplace.mode=0;
UltraEdit.activeDocument.findReplace.matchCase=false;
UltraEdit.activeDocument.findReplace.regExp=true;

var trigger = 1152.0
var expandby = 448.0
var regex = /(<Postion>)([0-9]*\.?[0-9]*)\s([0-9]*\.?[0-9]*)\s([0-9]*\.?[0-9]*)(<\/Postition>)/g;

while ( UltraEdit.activeDocument.findReplace.find(regex) && ! UltraEdit.activeDocument.isEof() ) {

  UltraEdit.activeDocument.selectLine();
  var line = UltraEdit.activeDocument.selection;
  var coor = line.match(regex);
 
  var xCoor = Number(coor[2]);
  if ( xCoor >= trigger ) {
    xCoor = xCoor + expandby
  }
 
  var yCoor = Number(coor[4]);
  if ( yCoor >= trigger ) {
    yCoor = yCoor + expandby
  }
 
  var node = "new <Postion>"+xCoor+" "+coor[3]+" "+yCoor+"<Postion>";

  UltraEdit.activeDocument.deleteLine();
  UltraEdit.activeDocument.write(node);
}
Can someone tell me what I did wrong?

Kind regards

PostJul 18, 2025#2

While testing further I found the second number in the XML node can be negative as well

Code: Select all

<Position>1333.596 -0.039164525 1220.3885</Position>
I fixed the regex (typos and possible negative) to:

Code: Select all

/(<Position>)([0-9]*\.?[0-9]*)\s([-]?[0-9]*\.?[0-9]*)\s([0-9]*\.?[0-9]*)(<\/Position)/g
Still the script does not change the file content.

PostJul 18, 2025#3

Solved. Using two regex does the trick. No idea why match and find don't understand the same syntax.

Code: Select all

UltraEdit.insertMode();
UltraEdit.perlReOn();
UltraEdit.activeDocument.top();
UltraEdit.activeDocument.findReplace.mode=0;
UltraEdit.activeDocument.findReplace.matchCase=false;
UltraEdit.activeDocument.findReplace.regExp=true;

var trigger = 1152.0
var expandby = 448.0
var node_regex = "<Position>.*</Position>";
var coor_regex = /(\d*\.?\d*)\s([-]?\d*\.?\d*)\s(\d*\.?\d*)/;
var regexMatch = 0;

while ( UltraEdit.activeDocument.findReplace.find(node_regex) && ! UltraEdit.activeDocument.isEof() ) {

  var line = UltraEdit.activeDocument.selection;
  var coor = line.match(coor_regex);
 
  regexMatch++;
 
  var xCoor = Number(coor[1]);
  if ( xCoor >= trigger ) {
    xCoor = xCoor + expandby
  }
 
  var yCoor = Number(coor[3]);
  if ( yCoor >= trigger ) {
    yCoor = yCoor + expandby
  }
 
  var node = "new <Postion>"+xCoor+" "+coor[2]+" "+yCoor+"<Postion>";

  // UltraEdit.activeDocument.deleteLine();
  UltraEdit.activeDocument.write(node);
}

UltraEdit.outputWindow.showStatus = false;
UltraEdit.outputWindow.clear();
UltraEdit.outputWindow.write("Matches " + regexMatch.toString(10));

6,826625
Grand MasterGrand Master
6,826625

PostJul 18, 2025#4

UltraEdit.activeDocument.findReplace.find() expects as parameter a JavaScript String object and not a JavaScript RegExp object. UltraEdit.activeDocument.findReplace.find() does nothing on passing an object of wrong type to the function instead of the search string which is passed to the selected regular expression engine of UltraEdit.

I suggest following enhanced script:

Code: Select all

UltraEdit.insertMode();
UltraEdit.activeDocument.top();
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;
UltraEdit.activeDocument.findReplace.searchInColumn=false;

var trigger = 1152.0;
var expandby = 448.0;
var node_regex = "<Position>[0-9]+\\.?[0-9]*[\\t ]+-?[0-9]+\\.?[0-9]*[\\t ]+[0-9]+\\.?[0-9]*</Position>";
var coor_regex = /([0-9]+\.?[0-9]*)[\t ]+(-?[0-9]+\.?[0-9]*)[\t ]+([0-9]+\.?[0-9]*)/;
var regexMatch = 0;

while ( UltraEdit.activeDocument.findReplace.find(node_regex) ) {

  var coor = UltraEdit.activeDocument.selection.match(coor_regex);
 
  regexMatch++;
 
  var xCoor = Number(coor[1]);
  if ( xCoor >= trigger ) {
    xCoor = xCoor + expandby;
  }
 
  var yCoor = Number(coor[3]);
  if ( yCoor >= trigger ) {
    yCoor = yCoor + expandby;
  }
 
  var node = "new <Postion>"+xCoor+" "+coor[2]+" "+yCoor+"<Postion>";

  // UltraEdit.activeDocument.deleteLine();
  UltraEdit.activeDocument.write(node);
}

UltraEdit.outputWindow.showStatus = false;
UltraEdit.outputWindow.clear();
UltraEdit.outputWindow.write("Matches " + regexMatch.toString(10));
There are all parameters for the Perl regular expression find defined by the script.

The expressions are modified to match only valid XML nodes.
  • \d matches all digits according to Unicode which are a lot more than the Latin 0 to 9.
    [0-9] is faster and more accurate for this task as matching just the Latin digits 0123456789.
  • \s matches all whitespace characters according to Unicode which are a lot more than horizontal tab and normal space.
    [\t ] is faster and more accurate for this task as matching just a horizontal tab or a normal space.
  • UltraEdit.activeDocument.isEof() is removed as the caret reaches for sure never the end of the file. The call of this function just makes the script slower.
  • Missing semicolons are added at the end of some lines.