当前位置: 首页 > 面试题库 >

lxml etree xmlparser删除不需要的名称空间

宗政金鹏
2023-03-14
问题内容

我有一个XML文档,我正在尝试使用Etree.lxml进行解析

<Envelope xmlns="http://www.example.com/zzz/yyy">
  <Header>
    <Version>1</Version>
  </Header>
  <Body>
    some stuff
  <Body>
<Envelope>

我的代码是:

path = "path to xml file"
from lxml import etree as ET
parser = ET.XMLParser(ns_clean=True)
dom = ET.parse(path, parser)
dom.getroot()

当我尝试获取dom.getroot()时,我得到:

<Element {http://www.example.com/zzz/yyy}Envelope at 28adacac>

但是我只想要:

<Element Envelope at 28adacac>

当我做

dom.getroot().find("Body")

我什么也得不到。但是,当我

dom.getroot().find("{http://www.example.com/zzz/yyy}Body")

我得到结果。

我认为将ns_clean = True传递给解析器将防止这种情况。

有任何想法吗?


问题答案:
import io
import lxml.etree as ET

content='''\
<Envelope xmlns="http://www.example.com/zzz/yyy">
  <Header>
    <Version>1</Version>
  </Header>
  <Body>
    some stuff
  </Body>
</Envelope>
'''    
dom = ET.parse(io.BytesIO(content))

您可以使用以下xpath方法找到可识别名称空间的节点:

body=dom.xpath('//ns:Body',namespaces={'ns':'http://www.example.com/zzz/yyy'})
print(body)
# [<Element {http://www.example.com/zzz/yyy}Body at 90b2d4c>]

如果您确实要删除名称空间,则可以使用XSL转换:

# http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl
xslt='''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>

<xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>
'''

xslt_doc=ET.parse(io.BytesIO(xslt))
transform=ET.XSLT(xslt_doc)
dom=transform(dom)

在这里,我们看到名称空间已被删除:

print(ET.tostring(dom))
# <Envelope>
#   <Header>
#     <Version>1</Version>
#   </Header>
#   <Body>
#     some stuff
#   </Body>
# </Envelope>

现在,您可以通过以下方式找到“身体”节点:

print(dom.find("Body"))
# <Element Body at 8506cd4>


 类似资料:
  • 我有一个列名称为空的dataframe: 我如何删除空列名而不考虑位置?

  • 问题内容: 我已经导入了WSDL并使用它发送SOAP请求。看起来像这样: 问题出在Calculate元素中。Web服务无法接受。Web服务不喜欢这样的名称空间… 使用SoapUI,我发现此请求可以正常工作: 那么,如何将请求从第一个版本更改为第二个版本?(不使用肮脏的把戏!) (如果会导致正确的请求格式,则重新导入不是问题。) 再说一遍:不允许使用任何肮脏的技巧,例如入侵请求流以对其进行修改! 尽

  • 2)如果我按照下面的方式编辑package-info,那么它是很好的,但是问题是我创建的是一个JAXB整数元素如下所示,前缀删除没有应用于这些元素

  • 我有以下xml。 我想要的是 我想做的是只使用名称空间xmlns:i=”获取节点GetPatientTreatmentTeamResult下的文本(该节点在不同的调用中会有所不同)http://www.w3.org/2001/XMLSchema-instance(所有调用都有这个)并且不使用实际的节点名。 我尝试过使用XmlParser和XmlSlurper 但我一直没能得到我想要的结果。 我该怎

  • 问题内容: 如何删除名称为特定的Cookie ? 不应以下内容: 然后: 杀死饼干? 问题答案: 您应该定义cookie所在的路径,以确保删除正确的cookie。 如果未指定路径,浏览器将相对于您当前所在的页面设置一个cookie,因此,如果您在其他页面上删除该cookie时,另一个cookie继续存在。 根据@Evan Morrison的评论进行编辑。 请注意,在某些情况下,要标识正确的cook

  • 我正在写一个实用程序之间的集成内部系统和第三方产品。我试图生成一个可以由第三方产品加载的xml文件,但我很难按照他们的要求生成xml。我已经创建了一个简化的版本,只是为了测试。 预期产出应如下: 我的代码如下: 主要: 课程类别: