DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> XMLStarlet 使用入門
XMLStarlet 使用入門
編輯:XML詳解     
了解如何通過 XMLStarlet 命令行工具、使用簡單的命令對 XML 進行格式化、轉換、修正和編輯。Jack Herrington 告訴您掌握這種強大的工具多麼輕而易舉,它可以大幅度地簡化您的工作。

XMLStarlet 是一種開放源碼的 XML 工具箱,可以在 UNIX?、Mac OS® X 或 Microsoft® Windows® 命令行中使用。XMLStarlet 可以驗證 XML、格式化 XML、選擇其中的一部分、用 XSLT 進行轉換甚至編輯。這意味著,不需要使用 Perl 或 Java® 之類的編程語言編寫任何自定義的代碼,就可以在 shell 腳本中加入 XML 工具。

使用 XMLStarlet 需要安裝它,而安裝需要 libxml2 和 libxslt2 庫。在 Windows 上不需要安裝 libxml2 和 libxslt2,因為 Win32 包已經包含了。可以下載 Win32 可執行文件並將其安裝到方便從命令行執行的任何位置。如果運行 UNIX,而機器上還沒有 libXML2 和 libxslt2,則必須下載並安裝(請參閱 參考資料)。

然後轉到 XMLStarlet 主頁下載最新的構建包(請參閱 參考資料)。運行 ./configure 腳本以便設置構建腳本,然後運行 make install 構建包並安裝。如果您不是超級用戶,應該使用 sudo make install 以便將命令安裝到 system 目錄中。

可能還需要訪問 XML、XSLT 和 XML Path Language (XPath) 頁面以便及時更新這三個標准,這對於充分利用 XMLStarlet 非常重要(請參閱 參考資料)。

基礎
安裝完成後,現在可以對 XMLStarlet 做一番漫游了。首先不帶參數運行 XML 命令(參見清單 1)。

清單 1. XMLStarlet 幫助頁


% xml

XMLStarlet Toolkit: command-line utilitIEs for XML

Usage: xml [<options>] <command> [<cmd-options>]

where <command> is one of:

ed    (or edit)      - Edit/Update XML document(s)

sel   (or select)    - Select data or query XML document(s) (XPATH, etc)

tr    (or transform) - Transform XML document(s) using XSLT

val   (or validate)  - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)

fo    (or format)    - Format XML document(s)

el    (or elements)  - Display element structure of XML document

c14n  (or canonic)   - XML canonicalization

ls    (or list)      - List directory as XML

esc   (or escape)    - Escape special XML characters

unesc (or unescape)  - Unescape special XML characters

pyx   (or xmln)      - Convert XML into PYX format (based on ESIS - ISO 8879)

p2x   (or depyx)     - Convert PYX into XML

<options> are:

--version            - show version

--help  - show help

Wherever file name mentioned in command help it is assumed

that URL can be used instead as well.



Type: xml <command> --help <ENTER> for command help



XMLStarlet is a command line toolkit to query/edit/check/transform

XML documents (for more information see http://XMLstar.sourceforge.Net/)

所有命令的基本格式為 XML <command>,後面跟一些選項。了解每個選項可以使用 XML <command> --help 命令。比如,清單 2 顯示了編輯(ed)命令的幫助。

清單 2. 編輯命令的幫助


% xml ed --help

XMLStarlet Toolkit: Edit XML document(s)

Usage: xml ed <global-options> {<action>} [ <xml-file-or-uri> ... ]

where

<global-options>  - global options for editing

<xml-file-or-uri> - input XML document file name/uri (stdin otherwise)



<global-options> are:

-P (or --pf)        - preserve original formatting

-S (or --ps)        - preserve non-significant spaces

-O (or --omit-decl) - omit XML declaration (<?xml ...?>)

-N <name>=<value>   - predefine namespaces (name without 'xmlns:')

ex: xsql=urn:Oracle-xsql

Multiple -N options are allowed.

-N options must be last global options.

--help or -h        - display help



where <action>

-d or --delete <xpath>

-i or --insert <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>

-a or --append <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>

-s or --subnode <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>

-m or --move <xpath1> <xpath2>

-r or --rename <xpath1> -v <new-name>

-u or --update <xpath> -v (--value) <value>

-x (--expr) <xpath> (-x is not implemented yet)



XMLStarlet is a command line toolkit to query/edit/check/transform

XML documents (for more information see http://XMLstar.sourceforge.Net/)

這份幫助文件看起來很復雜,但最重要的部分在下面,可以看到如何刪除、插入 XML 節點或者改變節點的值,等等。

長代碼行
本文中的一些代碼行很長,如果不斷開就無法在窗口中顯示出來。這些行在代碼清單中被折疊起來,雖然在實際的命令行中只有一行。這些行用 » 符號表示(比如清單 3)。

XML 目錄列表
使用 XMLStarlet 需要有 XML,因此我們介紹第一個命令 XML ls,它用 XML 給出當前目錄的列表。清單 3 給出了一個例子。

清單 3. XML 目錄列表


% xml ls

<xml>

    <d p="rwxr-xr-x" a="2005.05.04 23:03:46" 

    » m="2004.03.24 16:21:02" s="374" n="."/>

    <d p="rwxr-xr-x" a="2005.05.04 23:03:46" 

    » m="2005.05.04 22:13:41" s="1938"n=".."/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 01:13:43" s="6148"n=".DS_Store"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 00:41:46" s="173" n="build.xml"/>

    <d p="rwxr-xr-x" a="2005.04.30 11:34:27" 

    » m="2004.03.24 01:13:43" s="544" n="docs"/>
<f p="rw-r--r--" a="2005.03.24 17:53:52" » m="2004.03.21 18:41:58" s="641" n="input.XML"/> <f p="rw-r--r--" a="2005.03.24 17:53:52" » m="2004.03.23 23:41:15" s="3587"n="main.xsl"/> <f p="rw-r--r--" a="2005.03.24 17:53:52" » m="2004.03.24 00:37:10" s="184" n="Makefile"/> <f p="rw-r--r--" a="2005.03.24 17:53:52" » m="2004.03.24 00:36:41" s="3869"n="MyGenerator.class"/> <f p="rw-r--r--" a="2005.03.24 17:53:52" » m="2004.03.24 00:36:33" s="5265"n="MyGenerator.Java"/> <d p="rwxr-xr-x" a="2005.04.30 11:34:25" » m="2004.03.24 00:20:07" s="272" n="output"/> </XML> 

如果認為目錄列表顯示的信息太多了,可以(比方說)去掉目錄節點,如清單 4 所示。

清單 4. 不含目錄節點的列表


% xml ls | xml ed -d "//d"

<?xml version="1.0"?>

<xml>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 01:13:43" s="6148" n=".DS_Store"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 00:41:46" s="173" n="build.xml"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.21 18:41:58" s="641" n="input.XML"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.23 23:41:15" s="3587" n="main.xsl"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 00:37:10" s="184" n="Makefile"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 00:36:41" s="3869" n="MyGenerator.class"/>

    <f p="rw-r--r--" a="2005.03.24 17:53:52" 

    » m="2004.03.24 00:36:33" s="5265" n="MyGenerator.Java"/>

</XML>

使用編輯命令(ed)從 XML 中去掉了 d 節點。ls 命令把目錄輸出到標准輸出。管道符(|)將標准輸出重定向到編輯命令的標准輸入,編輯命令從列表中刪除 d 節點。使用 XPath 表達式 //d 指定 d 節點,它和樹中所有層次上的 d 節點匹配。如果要更加准確,可以使用 /XML/d

現在,假設要刪除 am 屬性(如清單 5 所示)。

清單 5. 刪除 a 和 m 屬性的目錄列表


% xml ls | xml ed -d "//d" -d "//@a" -d "//@m" -d "//@p"

<?xml version="1.0"?>

<xml>

    <f s="6148" n=".DS_Store"/>

    <f s="173" n="build.xml"/>

    <f s="641" n="input.XML"/>

    <f s="3587" n="main.xsl"/>

    <f s="184" n="Makefile"/>

    <f s="3869" n="MyGenerator.class"/>

    <f s="5265" n="MyGenerator.Java"/>

</XML>

現在更簡潔了,清單中只剩下了文件,文件節點中只能看到文件的大小和名稱。為了更便於跟蹤,可以將結果保存在一個名為 ls.XML 的文件中。也可使用 rename 編輯函數將 f 標簽修改為 file(如清單 6 所示)。

清單 6. 顯示大小和文件名屬性的目錄列表


% cat ls.xml | xml ed -r "//f" -v "file"

<?xml version="1.0"?>

<xml>

    <file s="6148" n=".DS_Store"/>

    <file s="173" n="build.xml"/>

    <file s="641" n="input.XML"/>

    <file s="3587" n="main.xsl"/>

    <file s="184" n="Makefile"/>

    <file s="3869" n="MyGenerator.class"/>

    <file s="5265" n="MyGenerator.Java"/>

</XML>

此外,如果標簽和屬性不願意使用短名字如 sn,可以分別將其修改為 sizename(如圖 7 所示)。

清單 7. 使用 file 標簽的目錄列表


% cat ls.xml | xml ed -r "//f" -v "file" -r "//@s" -v "size" -r "//@n" -v "name"

<?xml version="1.0"?>

<xml>

    <file size="6148" name=".DS_Store"/>

    <file size="173" name="build.xml"/>

    <file size="641" name="input.XML"/>

    <file size="3587" name="main.xsl"/>

    <file size="184" name="Makefile"/>

    <file size="3869" name="MyGenerator.class"/>

    <file size="5265" name="MyGenerator.Java"/>

</XML>

這樣讀起來更容易了。到現在還沒有寫一行 XSLT、Perl 或 Java 代碼。將該文件保存為 ls2.XML。

驗證
新的目錄列表看起來不錯,那麼是不是仍然有效呢?清單 8 說明了如何來進行判斷。

清單 8. 檢查 XML 的良構性


% xml val ls2.xml

ls2.XML - valid

啊,是有效的。就是說它是結構良好的,即標簽是平衡的、字符編碼是正確的等等。但是仍然可能缺少必要的標簽或者正確的標簽。為此必須知道文件的正確結構,因此需要一個模式。只有用模式檢查 XML 文檔並且通過之後才能說它是有效的。

清單 9 顯示了 XML 目錄列表文件的基本 RELAX NG 模式。

清單 9. RELAX NG 模式


<?xml version="1.0" encoding="UTF-8"?>

<grammar ns="" xmlns=http://relaxng.org/ns/structure/1.0

datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

  <start>

    <element name="XML">

      <oneOrMore>

        <element name="file">

          <attribute name="name">

            <data type="NMTOKEN"/>

          </attribute>

          <attribute name="size">

            <data type="integer"/>

          </attribute>
</element> </oneOrMore> </element> </start> </grammar> 

RELAX NG 讀起來很容易。最上面的 element 標簽定義了 XML 作為基本標簽。然後,XML 標簽中的 oneOrMore 標簽被命名為 filesize

ls2.XML 文件對於這個新的模式有效嗎?請參閱清單 10。

清單 10. 用模式檢查


% xml val -e -r ls.rng ls2.xml

ls2.XML - valid

如果您像我一樣 —— 只有看到錯誤才會滿足,那麼可以在 ls3.XML 文件中的一個文件節點中添加屬性 someAttribute,然後再檢查該文件(參見清單 11)。

清單 11. 用模式檢查錯誤的文件


% xml val -e -r ls.rng ls3.xml

ls3.xml:4: element file: Relax-NG validity error : 

» Invalid attribute someAttribute for element file

ls3.XML - invalid

結果證明失敗了。不但要知道文件是結構良好的,還要知道所有的標簽和屬性都是正確的。

文本
還可以使用選擇函數從 XML 提取數據元素。清單 12 中的例子從 XML 目錄中提取文件名作為普通文本。

清單 12. 提取文件名


% xml sel -t -m "/xml/file" -v "concat(@name,'&#10;')" ls2.xml

.DS_Store

build.xml

input.XML

main.xsl

Makefile

MyGenerator.class

MyGenerator.Java

這裡要注意兩點。首先,提取文件名的 XPath 是 /XML/file 條款。其次使用 -v 選項的輸出說名用回車換行連接 file 標簽中的 name 屬性。

現在增加 -s 選項,按照 size 屬性對文件排序(參見清單 13)。 A:N:- 語法告訴 XMLStarlet 按照數值大小遞增排序。(這裡將 size 參數添加到 concat 語句中以便能正常工作。)

清單 13. 列表排序


% xml sel -t -m "/xml/file" -s A:N:- "@size" -v "concat 

» ( @name,':',@size,'&#10;' ) " ls2.xml

build.xml:173

Makefile:184

input.XML:641

main.xsl:3587

MyGenerator.class:3869

MyGenerator.Java:5265

.DS_Store:6148

牛刀小試
為了讓 XML 命令做點實際工作,可以使用它解析一份交通報告。 Yahoo!® Maps 提供了交通服務,可以使用 curl 命令和 -g 選項(表示 GET)通過 RSS 下載最新的交通信息。比如在清單 14 中,通過添加 ?csz=94101 參數指定了我的郵政編碼,於是得到了舊金山最新的交通報告。

清單 14. 舊金山的交通報告(RSS)


% curl -g "http://maps.yahoo.com/traffic.rss?csz=94101" –s

<?XML version="1.0" encoding="ISO-8859-1" ?>

<rss version="2.0">

<channel>

<title>Yahoo! Maps Traffic -- San Francisco,  CA 94101</title>

<link>http://us.rd.yahoo.com/maps/mapresults/trfrssarea/*

» http://maps.yahoo.com/maps_result?csz=

» San+Francisco%2C++CA+94101&amp;country=

» us&amp;lat=37.775&amp;lon=

» -122.4183&amp;trf=1&amp;mag=5</link>

<category>Traffic</category>

<description>Yahoo! Maps Traffic -- 

» San Francisco,  CA 94101</description>

<language>en-us</language>

<ttl>3</ttl>

<lastBuildDate>Fri, 06 May 2005 16:33:59 -0700<

» /lastBuildDate>

<pubDate>Fri, 06 May 2005 18:31:27 CDT<

» /pubDate>

<copyright>Copyright (c) 2005 Yahoo! Inc. 

» All rights reserved.</copyright>

<item>

<title>

Incident, On I-580 At Seminary Ave

</title>

<description>

Traffic Collision, Severity: Major, Started: 04:20pm 05/06/05, 

» Estimated End: 04:50pm 05/06/05, 

» Last Updated: 04:25pm 05/06/05

</description>

<link>http://us.rd.yahoo.com/maps/mapresults/trfrssitem/*

» http://maps.yahoo.com/maps_result?csz=

» San+Francisco%2C++CA+94101&amp;mlt=

» 37.778234&amp;mln=-122.168438&amp;lat=

» 37.775&amp;lon=-122.4183&amp;trf=

» 1&amp;exctrf=1&amp;mag=4</link>

<pubDate>Fri, 06 May 2005 16:20:00 -0700</pubDate>

<category>Incident </category>

<severity>Major</severity>

<endDate>Fri, 06 May 2005 16:50:00 -0700</endDate>

<updatedDate>Fri, 06 May 2005 16:25:00 -0700<

» /updatedDate>

</item>

...

現在可以將 curl 命令的輸出通過 XMLStarlet 命令去除其中的描述部分(如清單 15 所示)。

清單 15. 通過 XMLStarlet 處理的交通 RSS


% curl -g "http://maps.yahoo.com/traffic.rss?csz=94101" 

» -s | XML sel -t -m "/rss/channel/item/description" -v "."

Traffic Collision, Severity: Major, Started: 04:20pm 05/06/05, 

» Estimated End: 04:50pm 05/06/05, 

» Last Updated: 04:25pm 05/06/05

Disabled Vehicle, Severity: Moderate, Started: 04:20pm 05/06/05, 

» Estimated End: 04:50pm 05/06/05, 

» Last Updated: 04:25pm 05/06/05

Disabled Vehicle, Severity: Moderate, Started: 04:19pm 05/06/05, 

» Estimated End: 04:49pm 05/06/05, 

» Last Updated: 04:25pm 05/06/05

Pedestrian On The Roadway, Severity: Critical, 

» Started: 04:17pm 05/06/05, 

» Estimated End: 04:47pm 05/06/05, » Last Updated: 04:25pm 05/06/05 Traffic Collision, Severity: Major, Started: 04:15pm 05/06/05, » Estimated End: 04:45pm 05/06/05, » Last Updated: 04:25pm 05/06/05 ... 

-m 選項從每個項中取出描述,然後使用 -v 選項通過句點(.)輸出節點中的文本。

結束語
本文粗略地介紹了這種強大的 XML 工具。有時間的話,不妨試一試 XMLStarlet 的 XSLT 轉換功能、方便的轉義和取消轉義功能以及 XML 格式化功能等等。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved