2009-07-06 4 views
4

Я использую ElementTree для анализа XML-файла. В некоторых полях будут отображаться данные HTML. Например, рассмотрим заявление следующим образом:HTML внутри узла с использованием ElementTree

<Course> 
    <Description>Line 1<br />Line 2</Description> 
</Course> 

Теперь предположим, что _course является переменной элемента, которые удерживают этот элемент Couse. Я хочу получить доступ к описанию этого курса, поэтому я:

desc = _course.find("Description").text; 

Но тогда desc содержит только строку «Линия 1». Я прочитал кое-что об атрибуте .tail, поэтому я также попробовал:

desc = _course.find("Description").tail; 

И я получаю тот же результат. Что делать, чтобы сделать desc «Строкой 1
Строка 2» (или буквально что-нибудь между и)? Другими словами, я ищу что-то похожее на свойство .innerText в C# (и многие другие языки, которые, как я полагаю).

ответ

3

У вас есть контроль над созданием xml-файла? Содержимое xml-тегов, которые содержат теги xml (или аналогичные), или символы разметки ('<' и т. Д.), Должны быть закодированы, чтобы избежать этой проблемы. Вы можете это сделать с помощью:

  • в CDATA разделе
  • Base64 или какой-либо другой кодировке (которая не включает в себя XML зарезервированные символы)
  • Entity кодирования ('< '==' &lt;')

Если вы не можете внести эти изменения, и ElementTree не может игнорировать теги, не включенные в xml-схему, вам придется предварительно обработать файл. Конечно, вам не повезло, если схема перекрывает html.

+0

Использование секции CDATA решить эту проблему. Благодаря! –

1

Символы, подобные «<» и «&», являются незаконными в элементах XML.

"<" будет генерировать ошибку, потому что синтаксический анализатор интерпретирует ее как начало нового элемента.

«&» будет генерировать ошибку, поскольку анализатор интерпретирует ее как начало символьной сущности.

Некоторые тексты, такие как код JavaScript, содержат много символов «<» или «&». Чтобы избежать ошибок, код сценария может быть определен как CDATA.

Все, что находится внутри секции CDATA, игнорируется синтаксическим анализатором.

CDATA раздел начинается с "":

Дополнительной информации о: http://www.w3schools.com/xmL/xml_cdata.asp

Надеется, что это помогает!

3

Вы пытаетесь прочитать атрибут tail из неправильного элемента.Попробуйте

desc = _course.find("br").tail; 

Атрибут tail используется для хранения конечных текстовых узлов при чтении XML-файлов смешанного содержания; текст, который следует непосредственно после того, как элемент хранится в атрибуте хвостового для этого элемента:

 
    <tag><elem>this goes into elem's 
    text attribute</elem>this goes into 
    elem's tail attribute</tag> 

Простой фрагмент кода для печати текста и хвост атрибутов из всех элементов в XML/XHTML.

 
import xml.etree.ElementTree as ET 

def processElem(elem): 
    if elem.text is not None: 
     print elem.text 
    for child in elem: 
     processElem(child) 
     if child.tail is not None: 
      print child.tail 

xml = '''<Course> 
    <Description>Line 1<br />Line 2 <span>child text </span>child tail</Description> 
    </Course>''' 

root = ET.fromstring(xml) 
processElem(root) 

Выход:

 
Line 1 
Line 2 
child text 
child tail 

http://code.activestate.com/recipes/498286-elementtree-text-helper/ см для лучшего решения. Он может быть изменен в соответствии с требованиями.

P.S. Я изменил свое имя от user839338, как указано в следующем посте

+0

Я почти не вижу решения, которые я использовал в этом случае в качестве обходного пути. Кодирование содержимого атрибута Description означало, что всякая семантика была включена в содержимое атрибута, была вне семантической области того, что описывало основное дерево XML. –

+2

Разница заключается в том, что принятое решение в основном рассматривает кодированный документ как * непрозрачный двоичный объект *, который может быть точным и значимым в семантике конкретного прилагаемого документа, но если конкретная сущность прилагаемого документа * ожидается, что * будет html, может быть более семантически полезно рассматривать xHTML как часть документа, а не как просто * полезную нагрузку * – SingleNegationElimination

1

Вдохновленный user839338's answer, я не искал разумного решения, которое выглядит примерно так.

>>> from xml.etree import ElementTree as etree 
>>> corpus = '''<Course> 
...  <Description>Line 1<br />Line 2</Description> 
... </Course>''' 
>>> 
>>> doc = etree.fromstring(corpus) 
>>> desc = doc.find("Description") 
>>> desc.tag = 'html' 
>>> etree.tostring(desc) 
'<html>Line 1<br/>Line 2</html>\n' 
>>> 

Там нет простой способ устранить окружающий тег (первоначально <Description>), но это легко модифицируется в то, что можно было бы использовать в случае необходимости, например, <div> или <span>

 Смежные вопросы

  • Нет связанных вопросов^_^