Skip to content

Instantly share code, notes, and snippets.

@rvantonder
Last active November 17, 2020 07:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rvantonder/324a4f1c3a46b15628b72745679bf821 to your computer and use it in GitHub Desktop.
Save rvantonder/324a4f1c3a46b15628b72745679bf821 to your computer and use it in GitHub Desktop.
xml-example.md

You can put the snippets below in a config.toml file and run it with

comby -config config.toml -matcher .xml -f <your file or file patterns like .xml>

Example 1: Simple case preserving indentation by matching leading indentation of a block, and capturing and preserving all whitespace inside the block. The indentation is reintroduced in the rewrite and there's no change to spaces inside the block.

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''where rewrite :[block] { "<version>:[v]</version>" -> "<version>0.0.0</version>" }'''

bit.ly/3lBTher

To match on blocks conditionally, we can do something like this:

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''
where match :[block] {
| "<groupId>:[g]</groupId>" -> :[g] == "javax.xml.bind"
}'''

This matches only if the first thing :[g] matched between <groupId> tags equals javax.xml.bind.

bit.ly/2Uy7tJy

To add more conditions:

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''
where match :[block] {
| "<groupId>:[g]</groupId> <artifactId>:[a]</artifactId>" -> :[g] == "javax.xml.bind", :[a] == "jaxb-api"
}'''

Says the same as the above for groupId, and then also for some thing :[a] between artifactId must be equal to jaxb-api.

We can use the conditions above with a rewrite rule for the version update. In this case, putting the rewrite rule inside or ouside the match block doesn't matter, but I'll just put it inside:

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''
where match :[block] {
| "<groupId>:[g]</groupId> <artifactId>:[a]</artifactId>" -> 
    :[g] == "javax.xml.bind", 
    :[a] == "jaxb-api",
    rewrite :[block] { "<version>:[v]</version>" -> "<version>0.0.0</version>" }
}'''

since there are more things to rewrite, we can add those too:

Final version

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''
where match :[block] {
| "<groupId>:[g]</groupId> <artifactId>:[a]</artifactId>" -> 
    :[g] == "javax.xml.bind", 
    :[a] == "jaxb-api"
},
rewrite :[block] { "<groupId>:[g]</groupId>" -> "<groupId>jakarta.xml.bind</groupId>" },
rewrite :[block] { "<artifactId>:[a]</artifactId>" -> "<artifactId>jakarta.xml.bind-api</artifactId>" },
rewrite :[block] { "<version>:[v]</version>" -> "<version>2.3.3</version>" }'''

bit.ly/36OrJwe

There may be more ways to go about it, but this is one way...

You may need to change :[indent~^\s+] to :[indent~^\s*] depending on your XML (if there is no leading indentation).

There's actually a way to simplify the rule above, depending on your data, we can just inline the javax.xml.bind or jaxb-api parts in the match rule:

Final version (alternative)

[hello]
match=''':[indent~^\s+]<dependency>:[block]</dependency>'''
rewrite=''':[indent]<dependency>:[block]</dependency>'''
rule='''
where match :[block] {
| ":[_]<groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId>:[_]" -> true
},
rewrite :[block] { "<groupId>:[g]</groupId>" -> "<groupId>jakarta.xml.bind</groupId>" },
rewrite :[block] { "<artifactId>:[a]</artifactId>" -> "<artifactId>jakarta.xml.bind-api</artifactId>" },
rewrite :[block] { "<version>:[v]</version>" -> "<version>2.3.3</version>" }'''

bit.ly/2IyLKif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment