How to tell lxml.etree.tostring(element) not to write namespaces in python?

后端 未结 3 364
你的背包
你的背包 2020-12-10 15:16

I have a huge xml file (1 Gig). I want to move some of the elements (entrys) to another file with the same header and specifications.

Let\'s say the original file co

相关标签:
3条回答
  • 2020-12-10 15:55

    This is more in comment to the answer by 'unutbu' in which a suggestion to cleanup namespace was desired without giving example. this might be what you are looking for...

    from lxml import objectify
    objectify.deannotate(root, cleanup_namespaces=True)
    
    0 讨论(0)
  • 2020-12-10 16:02

    I often grab a namespace to make an alias for it like this:

    someXML = lxml.etree.XML(someString)
    if ns is None:
          ns = {"m": someXML.tag.split("}")[0][1:]}
    someid = someXML.xpath('.//m:ImportantThing//m:ID', namespaces=ns)
    

    You could do something similar to grab the namespace in order to make a regex that will clean it up after using tostring.

    Or you could clean up the input string. Find the first space, check if it is followed by xmlns, if yes, delete the whole xmlns bit up to the next space, if no delete the space. Repeat until there are no more spaces or xmlns declarations. But don't go past the first >.

    0 讨论(0)
  • 2020-12-10 16:12

    There is a way to remove namespaces with XSLT:

    import io
    import lxml.etree as ET
    
    
    def remove_namespaces(doc):
        # 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)
        doc = transform(doc)
        return doc
    
    doc = ET.parse('data.xml')
    doc = remove_namespaces(doc)
    print(ET.tostring(doc))
    

    yields

    <some>
    
    <to_move date="somedate">
        <child>some text</child>
    </to_move>
    
    </some>
    
    0 讨论(0)
提交回复
热议问题