2008-08-26 20 views
11

Đôi khi tôi cần trích xuất nhanh một số dữ liệu tùy ý từ các tệp XML để đưa vào định dạng CSV. Thực hành tốt nhất của bạn để làm điều này trong thiết bị đầu cuối Unix là gì? Tôi rất thích một số ví dụ mã, ví dụ như thế nào tôi có thể giải quyết vấn đề sau?Phân tích cú pháp XML bằng cách sử dụng thiết bị đầu cuối unix

Ví dụ đầu vào XML:

<root> 
<myel name="Foo" /> 
<myel name="Bar" /> 
</root> 

đầu ra CSV mong muốn của tôi:

Foo, 
Bar, 

Trả lời

5

Nếu bạn chỉ muốn các thuộc tính tên của bất kỳ yếu tố, đây là một giải pháp nhanh chóng nhưng không đầy đủ.

(văn bản ví dụ của bạn là trong file dụ)

grep "tên" dụ | cắt -d "\"" -f2,2 | xargs -Tôi {} echo "{}"

9

Sử dụng một bộ xử lý XSLT dòng lệnh như xsltproc, saxon hoặc xalan để phân tích XML và tạo CSV. Dưới đây là an example, mà đối với trường hợp của bạn là stylesheet:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

    <xsl:template match="root"> 
     <xsl:apply-templates select="myel"/> 
    </xsl:template> 

    <xsl:template match="myel"> 
     <xsl:for-each select="@*"> 
      <xsl:value-of select="."/> 
      <xsl:value-of select="','"/> 
     </xsl:for-each> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 
11

Peter's answer là đúng, nhưng nó sẽ tạo ra thức ăn đường dấu

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="text"/> 
    <xsl:template match="root"> 
    <xsl:for-each select="myel"> 
     <xsl:value-of select="@name"/> 
     <xsl:text>,</xsl:text> 
     <xsl:if test="not(position() = last())"> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Chỉ. chạy ví dụ

xsltproc stylesheet.xsl source.xml 

để tạo ra các kết quả CSV vào đầu ra tiêu chuẩn.

1

Dưới đây là một kịch bản ruby ​​nhỏ mà không chính xác những gì câu hỏi của bạn yêu cầu (kéo một thuộc tính gọi là 'tên' ra khỏi các yếu tố được gọi là 'myel'). Nên dễ khái quát

#!/usr/bin/ruby -w 

require 'rexml/document' 

xml = REXML::Document.new(File.open(ARGV[0].to_s)) 
xml.elements.each("//myel") { |el| puts "#{el.attributes['name']}," if el.attributes['name'] } 
6

XMLStarlet là một bộ công cụ dòng lệnh để truy vấn/chỉnh sửa/séc/chuyển đổi tài liệu XML (để biết thêm thông tin, xem http://xmlstar.sourceforge.net/)

Không có tập tin để viết, chỉ ống tập tin của bạn để xmlstarlet và áp dụng một bộ lọc xpath.

cat file.xml | xml sel -t -m 'xpathExpression' -v 'elemName' 'đen' -v 'elname' -n -m biểu giá trị -v '' bao gồm đen newline -n ​​

Vì vậy, đối xpath của bạn biểu thức xpath sẽ là // myel/@ name sẽ cung cấp hai giá trị thuộc tính.

Công cụ rất tiện dụng.

HTH

+0

XMLStarlet dường như không được cập nhật gần đây – Vihung

0

tệp thử nghiệm của bạn có trong tệp test.xml.

sed -n 's/^\s`*`&lt;myel\s`*`name="\([^"]`*`\)".`*`$/\1,/p' test.xml 

Nó có đó là cạm bẫy, ví dụ nếu nó không được đưa ra đúng là mỗi myel là trên cùng một dòng, bạn phải "bình thường hóa" các tập tin xml đầu tiên (vì vậy mỗi myel là trên một dòng riêng biệt)

1

Trả lời câu hỏi ban đầu, giả sử tập tin xml là "test.xml" có chứa:

<root> <myel name="Foo" /> <myel name="Bar" /> </root>

cat text.xml | tr -s "\"" " " | awk '{printf "%s,\n", $3}'