LXML:如何忽略未知的名称空间前缀?

时间:2014-02-12 15:19:24

标签: python xml lxml mechanicalturk crowdsourcing

对于Crowdflower,我需要定义 CML ,因为它与我想要使用的XML非常相似 LXML执行此任务。 Crowdflower定义了它的CML标签,如:

  • <cml:textarea label="Sample text area:" />
  • <cml:checkbox label="A single checkbox with a default value" />

(取自Crowdflower网站:[1])

此外,这些 CML 文件通常不使用根元素。当我尝试使用lxml创建 CML 元素时,它会引发XMLSyntaxError。我想使用Is there a switch to ignore undefined namespace prefixes in LXML?中的解决方案,但创建的 CML 缺少根。

如何修改它忽略未知名称空间前缀的LXML?

代码

from lxml import etree

txt = "An example label"
txt_elm = etree.fromstring('<cml:text label="%s" />' % txt)

错误消息

txt_elm = etree.fromstring('<cml:text label="%s" />' % txt)
File "lxml.etree.pyx", line 2994, in lxml.etree.fromstring (src/lxml/lxml.etree.c:63296)
File "parser.pxi", line 1617, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:93649)
File "parser.pxi", line 1495, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:92453)
File "parser.pxi", line 1011, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:89097)
File "parser.pxi", line 577, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:84804)
File "parser.pxi", line 676, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:85904)
File "parser.pxi", line 616, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:85228)
lxml.etree.XMLSyntaxError: Namespace prefix cml on text is not defined, line 1, column 16

示例1

<h2>Image 1 :</h2>
<img src="{{urlmedia1}}" width="450" height="300">

<h2>Image 2 :</h2>
<img src="{{urlmedia2}}" width="450" height="300">

<cml:radios label="Which one of these two images conveys the most {{axis}} ?" validates="required">
   <cml:radio label="Image 1"/>
   <cml:radio label="Image 2"/>
</cml:radios>

示例2

<p>Focus on the emotion you feel when watching these shots. Which one convey?    <b>{{axis}}</b> the most ?</p>
<p>While you have the right to watch the shots as many times as you want, you should focus on your first impression.</p>
<hr/>
    <p>video 1: <em>{{miscdata1}}</em></p>
    <object style="height: 300px; width: 490px">
      <param name="movie" value="{{urlmedia1}}" />
      <param name="allowFullScreen" value="true" />
      <param name="allowScriptAccess" value="always" />
      <embed src="{{urlmedia1}}" type="application/x-shockwave-flash" allowfullscreen="false" allowScriptAccess="always" width="490" height="300"/>
    </object>
<hr/>
    <p>video 2: <em>{{miscdata2}}</em></p>
    <object style="height: 300px; width: 490px">
      <param name="movie" value="{{urlmedia2}}" />
      <param name="allowFullScreen" value="true" />
      <param name="allowScriptAccess" value="always" />
      <embed src="{{urlmedia2}}" type="application/x-shockwave-flash" allowfullscreen="false" allowScriptAccess="always" width="490" height="300"/>
    </object>
<hr/>
<cml:radios label="Which one conveys {{axis}} the most?" validates="required">
  <cml:radio label="Shot 1" />
  <cml:radio label="Shot 2" />
</cml:radios>

这两个例子都来自:2

注意:我的目标是构建一个CML结构,而不是解析一个。

1 个答案:

答案 0 :(得分:2)

使用ElementMaker(来自lxml)可以更容易地实现这一点:

from lxml.builder import ElementMaker
E = ElementMaker(namespace='cml', nsmap={'cml':'cml'})

cmlroot = E.root()
radios = E.radios(label='My question?', validates='required')
cmlroot.append(radios)
radios.append(E.radio(label='Image1'))
radios.append(E.radio(label='Image2'))

etree.dump(cmlroot)
<cml:root xmlns:cml="cml">
  <cml:radios validates="required" label="My question?">
    <cml:radio label="Image1"/>
    <cml:radio label="Image2"/>
  </cml:radios>
</cml:root>

然后,您可以通过剥离第一行和最后一行来获取所需的文本。

还有其他方法可以处理它,但我认为这是最简单的。

这对解析没有帮助,解析是它自己的问题之一,但适用于生成。