Switching from Linux and Windows to Mac OS X sometimes is not easy. And, if I can say, it's not even worthy, as Mac OS X is not so wonderful as many people say.
Anyway, I had to switch, and I'm learning how to do some things that I used to do before with my new Mac.
So, to keep it short, with Mac Os X there is a useful CLI utility to format an XML string. You can even format something that is in your clipboard and put it back in teh clipboard.
This is the command:
pbpaste | xmllint --format - | pbcopy
Visualizzazione post con etichetta XML. Mostra tutti i post
Visualizzazione post con etichetta XML. Mostra tutti i post
venerdì 8 aprile 2011
giovedì 8 ottobre 2009
Modify XML with groovy
One quite common thing to do when working with XML is to manipulate nodes: remove or rename attributes, changing values, remove or append nodes, and so on.
With Groovy's XmlParser this is quite easy, as explained in the official documentation.
Here are some more complex examples.
Suppose you want to set an attribute value, or to add the attribute if it doesn't exist. You can use this code:
If you want to rename an attribute:
Suppose you want to replace a child node with another one (in the same position). Since the children() method returns a list of nodes, you can do like this:
In this case we replace the child if there is only one node with that name, otherwise we replace the first one. Of course it's quite easy to replace all the children with a given name.
You can add these methods to a category or to the metaclass of the Node object to have them ready whenever needed.
With Groovy's XmlParser this is quite easy, as explained in the official documentation.
Here are some more complex examples.
Suppose you want to set an attribute value, or to add the attribute if it doesn't exist. You can use this code:
if (!node.attribute('myAtt') {
node.attributes().put('myAtt', 'myValue')
} else {
node.attributes()[myAtt] = 'myValue'
}If you want to rename an attribute:
def origAttrs = node.attributes()
if (origAttrs.containsKey(oldAtt)) {
origAttrs[myAtt] = origAttrs[oldAtt]
origAttrs.remove(oldAtt)
}
Suppose you want to replace a child node with another one (in the same position). Since the children() method returns a list of nodes, you can do like this:
def newChild = new Node(node, 'newChild', ['att1': 'val1'], 'New Text')
def indexOfChild = node.children().findIndexOf {it.name() == 'oldChildName'}
if (indexOfChild != -1) {
node.children()[indexOfChild] = newChild
newChild.parent = node
}
In this case we replace the child if there is only one node with that name, otherwise we replace the first one. Of course it's quite easy to replace all the children with a given name.
You can add these methods to a category or to the metaclass of the Node object to have them ready whenever needed.
martedì 1 settembre 2009
A regular expression to find XML tags
One common thing to do when dealing with XML files which are not well-formed, is to preprocess them to fix the problems. So you have to open them and to extract the xml tags. You can do this with a regular expression. The problem is that the regex has to find all XML tags but it should not match everything between < and >, because you could have the case when the text inside XML contains angular brackets. I couldn'd find on the web a regex that manages those cases, so I had to create one.
This regex covers most of these cases (except one...):
</?[A-Za-z][A-Za-z0-9]*(\\s+[a-zA-Z0-9]+=(\'|")?\\w*(\'|")?)*\\s*/?>
So, it matches every word starting and ending with angular brackets, that can have a / at the beginning or the end, starting with a letter followed by 0 or more letters or numbers. If there are attributes it look if there is at least one space, than a word, a = and another word. The double qoutes are left optional, since I want to catch also not-so-well-formed tags.
So for example, it matches <TAG>, </TAG>, <TAG/>, <TAG /> <TAG AT="OK">, <TAG AT=OK/> and so on.
It will not match anyway text like '< 10 mg and > 8 mg', '<100 and > 50' and so on.
The only problematic case is when you have a text like '<beta and=gamma > delta'. It's quite an unusual and weird case, so it isn't really a problem.
This regex covers most of these cases (except one...):
</?[A-Za-z][A-Za-z0-9]*(\\s+[a-zA-Z0-9]+=(\'|")?\\w*(\'|")?)*\\s*/?>
So, it matches every word starting and ending with angular brackets, that can have a / at the beginning or the end, starting with a letter followed by 0 or more letters or numbers. If there are attributes it look if there is at least one space, than a word, a = and another word. The double qoutes are left optional, since I want to catch also not-so-well-formed tags.
So for example, it matches <TAG>, </TAG>, <TAG/>, <TAG /> <TAG AT="OK">, <TAG AT=OK/> and so on.
It will not match anyway text like '< 10 mg and > 8 mg', '<100 and > 50' and so on.
The only problematic case is when you have a text like '<beta and=gamma > delta'. It's quite an unusual and weird case, so it isn't really a problem.
Iscriviti a:
Post (Atom)