3

I have a Cordova config.xml file and I'm writing a script to bump up the version. A sample of the file is:

<?xml version="1.0" encoding="utf-8"?>
<widget android-packageName="com.demo.android" id="com.demo.ios" ios-CFBundleIdentifier="com.demo.ios.dev" version="1.16.6" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name short="DEMO DEV">DEMO</name>

I want to replace the value of the attribute version that is inside the <widget> tag, but without affecting at all any other attribute, including the one in the <?xml tag.

So, simply put, find and replace the value of the attribute version inside the widget tag.

4
  • What have you tried already? Commented Oct 16, 2018 at 19:02
  • Use this regex to look for the version number (?<=\<widget.*(?<=version\=\"))(\d+\.?)+ and then replace the string with suitable replacement. Commented Oct 16, 2018 at 19:09
  • Javascript does not have look behind. Commented Oct 16, 2018 at 19:15
  • Is there only one widget tag. If not, can it possibly not have a version ? Because the whole <widget.*?version= thing just won't cut it. That's why I posted a hairy regex, to avoid such trivia, and is the only way it can be done. Commented Oct 19, 2018 at 20:16

3 Answers 3

5

You can try the following regex and test it on regex101:

/(<widget [\S\s]*?version=")[^"]+("[\S\s]*?>)/gmi

In short, what am I doing:

  1. Group everything from <widget to version="
  2. Select everything except a "
  3. Group everything until the next >.

You can then replace it with $1(new version)$2.

Here is a simple demo:

const versionRegex = /(<widget [\S\s]*?version=")[^"]+("[\S\s]*?>)/gmi;

const content = `<?xml version="1.0" encoding="utf-8"?>
<widget android-packageName="com.demo.android" id="com.demo.ios" ios-CFBundleIdentifier="com.demo.ios.dev" version="1.16.6" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name short="DEMO DEV">DEMO</name>`

const newVersion = 'testVersion';
const replaced = content.replace( versionRegex, `$1${ newVersion }$2` )
document.getElementById( 'result' ).innerText = replaced;
pre {
  white-space: pre-line;
}
<pre id="result"></pre>

Sign up to request clarification or add additional context in comments.

1 Comment

Doesn't span lines: regex101.com/r/e7oNcP/3. Even if you fix that, doesn't parse the widget tag correctly: regex101.com/r/e7oNcP/4
3

This do what you want:

let xml; // Your xml file
const version = "0.8.5"
xml = xml.replace(/(<widget.+version=")([0-9\.]+)(".*>)/, "$1"+version+"$3")

Explanation of regex matches:

  • First match of the regex ($1): first string which begin with <widget with all chars until version="
  • The second match ($2, not in the replace cause this is the string we want to replace) is the version number
  • The last match is all chars until caret closing > of the widget attribute.
  • And the global match is this three matches together

Comments

0

Try

Find /<widget(?=\s)(?=((?:[^>"']|"[^"]*"|'[^']*')*?\sversion\s*=\s*)(?:(['"])([\S\s]*?)\2)((?:"[\S\s]*?"|'[\S\s]*?'|[^>]*?)*?>))\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]*?)+>/

Replace <widget$1$2NEW_VERSION$2$4

https://regex101.com/r/1KnW0M/1

(The old version is in Capture Group 3 incase it's needed.)

More info

 # Begin Widget tag

 < widget                 
 (?= \s )
 (?=                           # Asserttion (a pseudo atomic group)
      (                             # (1 start), Up to Version attribute
           (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
           \s version \s* = \s* 
      )                             # (1 end)
      (?:
           ( ['"] )                      # (2), Quote
           ( [\S\s]*? )                  # (3), Version Value
           \2 
      )
      (                             # (4 start), After Version attribute
           (?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]*? )*?
           >
      )                             # (4 end)
 )

 # Have the version, just match the rest of tag

 \s+ 
 (?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]*? )+

 >                             # End Widget tag

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.