Como faço para analisar namespaces de um arquivo XML usando XMLLINT e BASH?

7

Abaixo, tenho um exemplo de um swidtag Adobe XML usado para rastrear o inventário. Eu preciso analisar informações relevantes usando xmllint no bash e saída para um novo arquivo de texto.

Por exemplo, gostaria de analisar o seguinte

swid:entitlement_required_indicator
swid:product_title
swid:product_version
swid:name
swid:numeric
swid:major
swid:minor
swid:build
swid:review

Eu tentei usar isso, mas não vai me deixar ler o namespace

xmllint --xpath '//swid:product_version/swid:name/text()' file.xml

Eu também tentei

xmllint --xpath "//*[local-name1()='product_version']/*[local-name2()='name']/text()" file.xml

Mas tenho esses erros

xmlXPathCompOpEval: function local-nameame1 not found
XPath error : Unregistered function
XPath error : Stack usage errror
XPath evaluation failure

Arquivo de tag de amostra para o Creative Suite 5 O exemplo a seguir é para o Adobe Photoshop CS5 serializado como Creative Suite 5 Master Collection (Suite)

<?xml version="1.0" encoding="utf-8"?>
<swid:software_identification_tag xsi:schemaLocation="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd" 
     xmlns:swid="http://standards.iso.org/iso/19770/-2/2008/schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<!--Mandatory Identity elements -->
<swid:entitlement_required_indicator>true</swid:entitlement_required_indicator>
<swid:product_title>Acrobat XI Pro</swid:product_title>
<swid:product_version>
    <swid:name>1.0</swid:name>
    <swid:numeric>
        <swid:major>1</swid:major>
        <swid:minor>0</swid:minor>
        <swid:build>0</swid:build>
        <swid:review>0</swid:review>
    </swid:numeric>
</swid:product_version>
<swid:software_creator>
    <swid:name>Adobe Systems Incorporated</swid:name>
    <swid:regid>regid.1986-12.com.adobe</swid:regid>
</swid:software_creator>
<swid:software_licensor>
    <swid:name>Adobe Systems Incorporated</swid:name>
    <swid:regid>regid.1986-12.com.adobe</swid:regid>
</swid:software_licensor>
<swid:software_id>
    <swid:unique_id>CreativeCloud-CS6-Mac-GM-MUL</swid:unique_id>
    <swid:tag_creator_regid>regid.1986-12.com.adobe</swid:tag_creator_regid>
</swid:software_id>

<swid:tag_creator>
    <swid:name>Adobe Systems Incorporated</swid:name>
    <swid:regid>regid.1986-12.com.adobe</swid:regid>
</swid:tag_creator>
<!--Optional Identity elements -->
<swid:license_linkage>
    <swid:activation_status>activated</swid:activation_status>
    <swid:channel_type>SUBSCRIPTION</swid:channel_type>
    <swid:customer_type>RETAIL</swid:customer_type>
</swid:license_linkage>
<swid:serial_number>909702426602037824854600</swid:serial_number>
</swid:software_identification_tag>
    
por macman 26.11.2012 / 22:48

4 respostas

12

Esta discussão é esclarecedora.

No mínimo, mesmo que não seja ideal, você deve ser capaz de fazer:

xmllint --xpath "//*[local-name()='product_version']/*[local-name()='name']/text()" file.xml

Ou use xmlstarlet em vez disso:

xmlstarlet sel -t -v //swid:product_version/swid:name file.xml
    
por 26.11.2012 / 23:22
2

Com uma versão mais antiga do xmllint (que não suporta --xpath), você pode definir um namespace e consultá-lo de forma mais intuitiva (mas você precisa limpar algum lixo adicional):

#!/bin/bash
echo 'setns swid=http://standards.iso.org/iso/19770/-2/2008/schema.xsd
      cat //swid:product_version/swid:name/text()' | \
xmllint --shell file.xml | egrep -v '^(/ >| -----)'
    
por 13.10.2015 / 21:05
1

Eu tive problemas semelhantes, lendo pom.xml (um arquivo de configuração do maven) no shell script para jenkins. Para garantir um bom resultado, eu faria:

xmllint --xpath "//swid:software_identification_tag/*[local-name()='product_version']/*[local-name()='name']/text()" file.xml

Você não parece ter o problema aqui se seu xml tiver esse tipo de conteúdo adicional:

<swid:product_specifics>
<swid:product_version>
...
</swid:product_version>
</swid:product_specifics>

xmllint --xpath "//*[local-name()='product_version']/*[local-name()='name']/text()" file.xml não funciona

Na minha situação, um pom.xml tem muitos elementos de "versão", portanto, se você quiser um específico, o caminho deve ser exato, caso contrário, você obterá vários valores que não deseja.

    
por 11.09.2014 / 11:59
1

Tente usar um aqui-doc. Exemplo:

#!/bin/bash
xmllint --shell file.xml <<EOF
setns swid=http://standards.iso.org/iso/19770/-2/2008/schema.xsd
xpath //swid:product_version/swid:name/text()
EOF

Funciona com versões posteriores de xmllint que suportam o parâmetro --xpath .

    
por 25.09.2017 / 06:01

Tags