Como extraio um único atributo de um arquivo XML?

Como extraio um único atributo de um arquivo XML?

Não estou muito familiarizado com regex, sed, etc. e estou com preguiça de descobrir neste momento, então como faço para extrair esta linha:

<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

Deixe-me saber se é necessária mais estrutura xml.

Responder1

Como os dados de entrada (seu arquivo XML) são estruturados, é melhor usar uma consulta nesses dados estruturados, em vez de tratá-los como texto simples e mexer com expressões regulares.

Podemos usar xmllint --xpathpara avaliar uma expressão XPath na sua entrada xml:

$ xmllint --xpath 'string(rss/channel/*[local-name()="astronomy"]/@sunrise)' weather.xml
6:48 am

- isso é um pouco complicado, pois temos que lidar com os diferentes namespaces nesse arquivo, mas funciona mesmo assim.

Para obter mais informações sobre XPath, a especificação está emhttp://www.w3.org/TR/xpath/

Responder2

Você não usa regex ou sed. Você usa um analisador XML e uma linguagem de consulta XML (XPath ou XQuery). E temo que os detalhes dependam do contexto: por exemplo, "yweather" é um nome abreviado (prefixo) para um namespace, e você precisa saber qual namespace ele representa.

Responder3

A resposta correta, como diz Michael Kay, é usar uma ferramenta específica para XML.

Para uma solução rápida e suja, aqui está uma abordagem sed. Vamos começar com este arquivo:

$ cat file
<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

Para extrair a hora do pôr do sol:

$ sed -rn 's/.*sunset="([^"]*)".*/\1/p' file
7:06 pm

Para entender o regex, vamos dividi-lo em três partes:

  1. .*partidas desde o início da escalação até a segunda parte

  2. Esta parte, sunset="([^"]*)", corresponde aos caracteres sunset=", seguidos por qualquer número de caracteres, exceto ", seguido pelo fechamento ". A expressão [^"]significa qualquer caractere, exceto "e [^"]*significa qualquer número desses caracteres. Os parênteses, (...), capturam os caracteres dentro do "..."grupo 1 do sed, que posteriormente referenciaremos como \1.

  3. .* corresponde a todos os caracteres após a expressão do pôr do sol.

Responder4

vou dar a mesma resposta deJeremy Kerrmas dando um xmlexemplo.

Temos um arquivo xml chamado config.xmlem nossa pasta raiz e queremos ler um atributo ou propriedade de uma tag, seja a widgettag.

config.xml:

<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="16" id="co.app.world" ios-CFBundleVersion="0.1.3" version="3.0.5" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>AppName</name>
    <description>Description.</description>
    <author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
</widget>

Queremos obter o android-versionCodevalor da propriedade, digitamos isto no terminal:

xmllint --xpath "string(//*[local-name()='widget']/@android-versionCode)" config.xml

Saída:

16

Explicação: usamos /*[local-name()='widget']para mapear a widgettag e depois @android-versionCodeler a propriedade desta.

informação relacionada