Você mencionou nos comentários que deseja algo portátil. Isso é admirável, mas eu realmente exorto você a não fazer isso de qualquer maneira. XML
é uma linguagem contextual e regex não é. Não há como uma expressão regular analisar o XML corretamente como resultado.
Na melhor das hipóteses, você recebe um hack, que só é válido desde que o XML permaneça no mesmo formato. Mas como a especificação XML diz que o formato pode acaso e reter a mesma semântica, isso é uma suposição perigosa e cria um código frágil.
Eu sei que você tem motivos para querer fazer isso - você já tem uma resposta que lhe dá um jeito de fazer isso. Eu sugeriria que um analisador ainda é a resposta correta .
Mas com analisadores XML, você obtém xpath
- que é muito parecido com expressões regulares, mas é aplicável a informações hierárquicas.
Algo parecido com isto:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parse ( \*DATA );
my $version = $twig -> get_xpath('//item/artifactId[string()="myproject"]/../version',0)->text;
print $version;
__DATA__
<xml>
<item>
<artifactId>myproject</artifactId>
<version>1.14.0-SNAPSHOT</version>
</item>
</xml>
Espero que você possa ver como o xpath
está funcionando? //item
encontra um item em qualquer lugar dentro da estrutura. [string()=
consulta o conteúdo do texto. Você poderia fazer algo como [@someAtt="fish"]
para verificar um atributo.
Então, ..
up (para item
) e obtemos o elemento version
.
Em seguida, obtenha o valor text
.
Como um oneliner:
perl -MXML::Twig -0777 -e 'print XML::Twig -> parse ( <> ) -> get_xpath('/item/artifactId[string()="myproject"]/../version',0)->text,"\n" yourxmlfile.xml
Agora, estou sugerindo XML::Twig
porque acho mais fácil aprender. XML::LibXML
também é muito bom.
Mas ele é distribuído com o strawberry perl no Windows e está disponível em muitos gerenciadores de pacotes - ou em CPAN
.
Alternativamente - xmlstarlet
deve permitir que você faça praticamente a mesma coisa.