Đó là đáng kể dễ dàng với lxml *, sử dụng parse()
và tostring()
chức năng:
from lxml.etree import parse, tostring
Trước tiên, bạn phân tích doc và nhận được yếu tố của bạn (Tôi đang sử dụng XPath, nhưng bạn có thể sử dụng bất cứ điều gì bạn muốn):
doc = parse('test.xml')
element = doc.xpath('//text')[0]
chức năng tostring()
trả về một đại diện văn bản của nguyên tố của bạn:
>>> tostring(element)
'<text>Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
Tuy nhiên, bạn không muốn các yếu tố bên ngoài, vì vậy chúng ta có thể loại bỏ chúng với một đơn giản str.replace()
gọi:
>>> tostring(element).replace('<%s>'%element.tag, '', 1)
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
Lưu ý rằng str.replace()
nhận 1 là tham số thứ ba, vì vậy nó sẽ loại bỏ chỉ sự xuất hiện đầu tiên của thẻ mở. Người ta cũng có thể làm điều đó với thẻ đóng.Bây giờ, thay vì 1, chúng ta vượt qua -1 để thay thế:
>>> tostring(element).replace('</%s>'%element.tag, '', -1)
'<text>Some <text>text with <extradata>data</extradata> in it.\n'
Các giải pháp, tất nhiên, là để làm tất cả mọi thứ cùng một lúc:
>>> tostring(element).replace('<%s>'%element.tag, '', 1).replace('</%s>'%element.tag, '', -1)
'Some <text>text with <extradata>data</extradata> in it.\n'
EDIT: @Charles làm một điểm tốt : mã này rất mong manh vì thẻ có thể có thuộc tính. Một giải pháp được nêu ra vẫn còn hạn chế có thể là để phân chia các chuỗi tại >
đầu tiên:
>>> tostring(element).split('>', 1)
['<text',
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n']
có được chuỗi kết quả thứ hai:
>>> tostring(element).split('>', 1)[1]
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
sau đó rsplitting nó:
>>> tostring(element).split('>', 1)[1].rsplit('</', 1)
['Some <text>text</text> with <extradata>data</extradata> in it.', 'text>\n']
và cuối cùng nhận được kết quả đầu tiên:
>>> tostring(element).split('>', 1)[1].rsplit('</', 1)[0]
'Some <text>text</text> with <extradata>data</extradata> in it.'
Tuy nhiên, mã này vẫn còn mong manh, vì >
là một char hoàn toàn hợp lệ trong XML, ngay cả bên trong các thuộc tính.
Dù sao, tôi phải thừa nhận rằng MattH solution là giải pháp chung, thực sự.
* Thực ra, giải pháp này cũng hoạt động với ElementTree, điều tuyệt vời nếu bạn không muốn phụ thuộc vào lxml. Điểm khác biệt duy nhất là bạn sẽ không có cách nào để sử dụng XPath.
OP muốn lấy nội dung của một yếu tố cụ thể. Giải pháp của bạn không hoạt động trong trường hợp này, ít nhất là không trực tiếp. II lấy một phần tử với 'e = t.xpath ('// text') [0]' và thử nó (''' .join (map (etree.tostring, e))') nhưng kết quả là '' dữ liệu trong đó.''. –
brandizzi
@brandizzi Điểm tốt. Cập nhật để phản ánh điều đó. – Marcin
Cần thử nghiệm trên một số trường hợp khác, nhưng ví dụ cuối cùng của bạn hoạt động tốt cho tôi (cho đến nay). Khi sử dụng 'find' thay cho' xpath', nó cũng hoạt động với '' etree'' chuẩn. – Brutus