From: André K. <ak...@la...> - 2010-11-21 16:23:24
|
Hi all, I've put an "enhanced" xml select version in the 'enhanced_select' branch. The most useful switches to me currently are --var, --key and -- choose/--when/--otherwise. But --import might be useful also. The --function/--param/--call-template/--with-param needs some thinking since it's too verbose to my taste. I use variables mostly for clarity, and since they can hold nodesets, it makes it easier to collect data from several places in an xml document (or even several times from the same place). A basic example (multiplication tables above 2) $ cat a.xml <x> <n>0</n> <n>1</n> <n>2</n> <n>3</n> <n>4</n> <n>5</n> <n>6</n> <n>7</n> <n>8</n> <n>9</n> </x> $ cat a.xml \ | xml sel \ --text \ --var numbers='//n' \ -t \ -m '$numbers[. >= 2]' \ --var i='.' \ -o '== Multiplication table of ' -v '$i' -o ' ==' -n \ -m '$numbers' \ --var j='.' \ -v '$i' -o ' * ' -v '$j' -o ' = ' -v '$i * $j' -n \ -b \ -b \ -b == Multiplication table of 2 == 2 * 0 = 0 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 2 * 4 = 8 ... == Multiplication table of 9 == ... 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81 Here's a little script which dumps the structure of an XML document and demonsrates the use of --var and --choose/--when/--otherwise switches. $ cat struct.sh #!/bin/sh struct() { "${xml:-xml}" sel \ "$@" \ --text \ --var empty="''" \ --var dot="'.'" \ --var plus="'+'" \ -t \ --var nl -n -b \ --var PI -o 'PI ' -b \ --var comm -o 'Comm' -b \ --var text -o 'Text' -b \ --var NS -o 'NS ' -b \ --var attr -o 'Attr' -b \ --var elem -o 'Elem' -b \ --var root -o 'Root' -b \ --var NA -o 'N/A ' -b \ -m '/|//node()|//@*' \ --var path \ -o '/' \ -m 'ancestor-or-self::*' \ -i 'position() > 1' -o '/' -b \ -v 'name()' \ -b \ -b \ --var indent \ -m 'ancestor-or-self::*' -v '$plus' -b \ -m 'ancestor-or-self::*' -v 'concat($dot, $dot, $dot)' -b \ -b \ --var type \ --var ns='../namespace::*' \ --choose \ --when './self::processing-instruction()' -v '$PI' - b \ --when 'count(.|$ns) = count($ns)' -v '$NS' - b \ --when './self::comment()' -v '$comm' - b \ --when './self::text()' -v '$text' - b \ --when 'count(.|../@*) = count(../@*)' -v '$attr' - b \ --when './self::*' -v '$elem' - b \ --when 'not(./parent::*)' -v '$root' - b \ --otherwise -v '$NA' -b \ -b \ -b \ --choose \ --when '$type = $PI' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v 'name()' -o '][' -v '.' \ -o ']' -n \ -b \ --when '$type = $comm' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v '.' -o ']' -n \ -b \ --when '$type = $text' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v '$path' -o '][' -v 'str:replace(., $nl, "\n")' -o ']' -n \ -b \ --when '$type = $attr' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v '$path' -o '][@' -v 'name()' -o '][' -v '.' -o ']' -n \ -b \ --when '$type = $root' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v '$path' -o ']' -n \ -b \ --when '$type = $elem' \ -v '$type' -o ': ' -v '$indent' \ -o '[' -v '$path' -o ']' \ -n \ --var nslist \ -m 'namespace::*[name() != "xml"]' \ -s 'A:T:U' 'name()' \ -i 'position() > 1' -o ', ' -b \ --choose \ --when 'name() = $empty' -o '<def>' -b \ --otherwise -v 'name()' -b \ -b \ -o '=' -v '.' \ -b \ -b \ -o 'NS ' -o ': ' -v '$indent' \ -o '[' -v '$path' -o '][' -v '$nslist' -o ']' -n \ -b \ --otherwise \ -v '$type' -o ': ' -v '$indent' \ -o '[' -c '.' -o ']' -n \ -b \ -b \ -b } struct "$@" $ cat eg.xml <?xml version="1.0"?> <?pi value="3.141592"?> <x xmlns="http://a.org"> <!-- Sample --> <t id="1">Text 1 <b>Text 2</b> Text 3</t> <t id="2"> Multi Line Text </t> <ns xmlns:b="http://b.net" xmlns:c="http://c.com"> <b:s>1</b:s> <c:s>2</c:s> </ns> </x> $ cat eg.xml | struct.sh Root: [/] PI : [pi][value="3.141592"] Elem: +...[/x] NS : +...[/x][<def>=http://a.org] Text: +...[/x][\n ] Comm: +...[ Sample ] Text: +...[/x][\n ] Elem: ++......[/x/t] NS : ++......[/x/t][<def>=http://a.org] Attr: ++......[/x/t][@id][1] Text: ++......[/x/t][Text 1 ] Text: +...[/x][\n ] Elem: +++.........[/x/t/b] NS : +++.........[/x/t/b][<def>=http://a.org] Text: +++.........[/x/t/b][Text 2] Text: ++......[/x/t][ Text 3] Elem: ++......[/x/t] NS : ++......[/x/t][<def>=http://a.org] Attr: ++......[/x/t][@id][2] Text: ++......[/x/t][\nMulti\n Line\n Text\n] Text: +...[/x][\n ] Elem: ++......[/x/ns] NS : ++......[/x/ns][<def>=http://a.org, b=http://b.net, c=http:// c.com] Text: ++......[/x/ns][\n ] Text: +++.........[/x/ns/b:s][1] Text: ++......[/x/ns][\n ] Elem: +++.........[/x/ns/c:s] NS : +++.........[/x/ns/c:s][<def>=http://a.org, b=http://b.net, c=http://c.com ] Text: +++.........[/x/ns/c:s][2] Text: ++......[/x/ns][\n ] Text: +...[/x][\n] Elem: +++.........[/x/ns/b:s] NS : +++.........[/x/ns/b:s][<def>=http://a.org, b=http://b.net, c=http://c.com ] Note there seems to be a misplaced 'Text: +...[/x][\n ]' right after 'Text: ++......[/x/t][Text 1 ]' It should be right after 'Text: ++......[/x/t][ Text 3]' but probably the order of nodes in a nodeset is not guaranteed. With other XSLT processors, the result may be different. I can provide some examples on how to use key and function switches. Regards, André |