Làm cách nào để phân tích các không gian tên từ một tệp XML bằng XMLLINT và BASH


7

Dưới đây tôi có một ví dụ về một swidtag Adobe XML được sử dụng để theo dõi hàng tồn kho. Tôi cần phân tích thông tin liên quan bằng cách sử dụng xmllint trong bash và xuất thông tin đó sang tệp văn bản mới.

Ví dụ tôi muốn phân tích cú pháp như sau

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

Tôi đã thử sử dụng cái này, nhưng nó sẽ không cho tôi đọc không gian tên

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

Tôi cũng đã thử

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

Nhưng có những lỗi này

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

Tệp thẻ mẫu cho Creative Suite 5 Mẫu sau đây dành cho Adobe Photoshop CS5 được xê-ri hóa dưới dạng 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>

Câu trả lời:


13

Cuộc thảo luận này là khai sáng.

Ít nhất, ngay cả khi không lý tưởng, bạn sẽ có thể làm:

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

Hoặc sử dụng xmlstarlet thay thế:

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

Các cuộc thảo luận bạn liệt kê là rất khai sáng, cảm ơn bạn. Với "// * [local-name () = 'product_version'] là tên cục bộ, một cái gì đó mà tôi tạo? Ex." // * [name1 () = 'product_version']. Tôi đã thử đổi tên nó và nhận được
macman

2

Với phiên bản cũ hơn của xmllint (không hỗ trợ --xpath), bạn có thể đặt một không gian tên và truy vấn trực quan hơn do đó (nhưng bạn phải tìm ra một số rác bổ sung):

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

tốt đẹp và rõ ràng. đã sử dụng một cách tiếp cận tương tự trong câu trả lời của tôi dưới đây.
roblogic

2

Hãy thử sử dụng tài liệu ở đây. Thí dụ:

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

Hoạt động với các phiên bản sau xmllintđó hỗ trợ --xpaththam số.


1

Tôi gặp vấn đề tương tự, đọc pom.xml (tệp cấu hình maven) trong tập lệnh shell cho jenkins. Để đảm bảo kết quả tốt, tôi sẽ làm:

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

Bạn dường như không gặp vấn đề gì ở đây nếu xml của bạn có loại nội dung bổ sung đó:

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

xmllint --xpath "//*[local-name()='product_version']/*[local-name()='name']/text()" file.xml sẽ không làm việc

Trong tình huống của tôi, pom.xml có nhiều phần tử "phiên bản", vì vậy nếu bạn muốn một phần tử cụ thể, đường dẫn phải chính xác, nếu không, bạn sẽ nhận được nhiều giá trị mà bạn không muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.