Как разобрать пространства имен из XML-файла с помощью XMLLINT и BASH

Ниже приведен пример swidtag Adobe XML, используемый для отслеживания инвентаря. Мне нужно разобрать соответствующую информацию с помощью xmllint в bash и вывести ее в новый текстовый файл.

Например, я хотел бы проанализировать следующие

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

Я попытался использовать это, но он не позволит мне прочитать пространство имен

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

Я тоже пробовал

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

Но получили эти ошибки

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

Пример файла тега для Creative Suite 5 Следующий пример предназначен для Adobe Photoshop CS5, сериализованного как 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> 

  • Как создать XML-документ из grep-вывода
  • Parse JSON или XML при загрузке
  • Прокрутите только архив данных .zip только для чтения, чтобы извлечь строку из файла .kml в
  • Как разбирать XML-файл в сценарии оболочки
  • конвертировать xml в csv
  • создать файл XML с помощью сценария bash
  • Как проверить корректность XML-файла 4 ГБ?
  • Как добавить строку, которая не начинается с '<' до предыдущей строки
  • 4 Solutions collect form web for “Как разобрать пространства имен из XML-файла с помощью XMLLINT и BASH”

    Это обсуждение является просветительской.

    По крайней мере, даже если это не идеально, вы должны быть в состоянии сделать:

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

    Вместо этого используйте xmlstarlet :

     xmlstarlet sel -t -v //swid:product_version/swid:name file.xml 

    У меня были подобные проблемы, читая pom.xml (файл конфигурации maven) в сценарии оболочки для jenkins. Чтобы обеспечить хороший результат, я бы сделал:

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

    Кажется, у вас нет проблемы, если ваш xml имеет такой дополнительный контент:

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

    xmllint --xpath "//*[local-name()='product_version']/*[local-name()='name']/text()" file.xml не будет работать

    В моей ситуации, pom.xml имеет много элементов «версии», поэтому, если вы хотите указать конкретный, путь должен быть точным, иначе вы получите несколько значений, которые вы не хотите.

    С более старой версией xmllint (которая не поддерживает -xpath) вы можете установить пространство имен и запросить более интуитивно таким образом (но вам нужно вытереть лишний мусор):

     #!/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 '^(/ >| -----)' 

    Попробуйте использовать здесь-doc. Пример:

     #!/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 

    Работает с более поздними версиями xmllint которые поддерживают параметр --xpath .

    Linux и Unix - лучшая ОС в мире.