假设我有一个 XML 字符串:
<A>
<B foo="123">
<C>thing</C>
<D>stuff</D>
</B>
</A>
我想插入一个 XML 模式使用的类型的命名空间,在所有元素名称前放置一个前缀。
<A xmlns:ns1="www.example.com">
<ns1:B foo="123">
<ns1:C>thing</ns1:C>
<ns1:D>stuff</ns1:D>
</ns1:B>
</A>
有没有办法使用 lxml.etree
或类似的库来做到这一点(除了蛮力查找替换或正则表达式)?
最佳答案
我认为仅使用 ElementTree 无法做到这一点。
操作 namespace 有时会非常棘手。 SO 上有很多关于它的问题。即使使用更高级的 lxml图书馆,真的很难。查看这些相关问题:
- lxml: add namespace to input file
- Modify namespaces in a given xml document with lxml
- lxml etree xmlparser remove unwanted namespace
下面是一个使用 XSLT 的解决方案。
代码:
from lxml import etree
XML = '''
<A>
<B foo="123">
<C>thing</C>
<D>stuff</D>
</B>
</A>'''
XSLT = '''
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="www.example.com">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="*">
<xsl:element name="ns1:{name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<!-- No prefix on the A element -->
<xsl:template match="A">
<A xmlns:ns1="www.example.com">
<xsl:apply-templates select="node()|@*"/>
</A>
</xsl:template>
</xsl:stylesheet>'''
xml_doc = etree.fromstring(XML)
xslt_doc = etree.fromstring(XSLT)
transform = etree.XSLT(xslt_doc)
print transform(xml_doc)
输出:
<A xmlns:ns1="www.example.com">
<ns1:B foo="123">
<ns1:C>thing</ns1:C>
<ns1:D>stuff</ns1:D>
</ns1:B>
</A>
关于python - 如何使用 Python 将命名空间和前缀插入到 XML 字符串中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31864133/