【问题标题】:Strip some tags and rename them剥离一些标签并重命名它们
【发布时间】:2019-09-21 14:18:44
【问题描述】:

使用 lxml 库,拥有这个 doc xml 文件,我想剥离一些标签并重命名它们:doc.xml

<html>
    <body>
        <h5>Fruits</h5>
        <div>This is some <span attr="foo">Text</span>.</div>
        <div>Some <span>more</span> text.</div>
        <h5>Vegetables</h5>
        <div>Yet another line <span attr="bar">of</span> text.</div>
        <div>This span will get <span attr="foo">removed</span> as well.</div>
        <div>Nested elements <span attr="foo">will <b>be</b> left</span> alone.</div>
        <div>Unless <span attr="foo">they <span attr="foo">also</span> match</span>.</div>
    </body>
</html>

而不是 html,body 将所有内容包装在“p 标签”中,而不是使用 h5 和每个 div 来包装所有内容,例如下面使用 lxml 的示例: 我的问题是如何从一种格式以下面的格式包装所有内容?

<p>
<h5 title='Fruits'> 
<div>This is some <span attr='foo'>Test</span>.</div>
<div>Some<span>more</span>text.</div>
</h5>
<h5 title='Vegetables'>
<div>Yet another line <span attr='bar'>of</span>text.</div>
....
</h5>
</p>

使用lxml,剥离标签:

tree = etree.tostring(doc.xml)
tree1 = lxml.html.fromstring(tree)
etree.strip_tags(tree1, 'body')

有人对此有任何想法吗?

【问题讨论】:

  • 欢迎来到 SO。请使用tour 并花时间阅读How to Ask 以及该页面上的其他链接。这不是讨论论坛或教程服务。
  • @wwii 忘了问问题

标签: python


【解决方案1】:
  • 创建一个只有&lt;p&gt; 标记的新文档
  • 迭代原始文档中&lt;body&gt; 标记的后代。
    • 将标签从原始文档添加到新文档 - 作为其&lt;p&gt; 标签的后代
      • 如果遇到&lt;h5&gt; 标签;将&lt;h5&gt; 标签添加到&lt;p&gt; 标签
        • 并将后续标签作为后代添加到它(&lt;h5&gt;

【讨论】:

  • 你能提供一个小前任吗?
  • 由于您没有提供任何您遇到问题的代码并询问 如何 做某事,我认为您正在寻找一种算法。
  • @Andrew - 这回答了你的问题吗?
【解决方案2】:

这是一个使用 lxml 的 xslt 解决方案。它将处理卸载到 libxml。我已将 cmets 添加到转换样式表中:

from lxml import etree

xsl = etree.XML('''
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <p>
            <xsl:apply-templates select="html/body"/>
        </p>
    </xsl:template>

    <!-- match body, but do not add content; this excludes /html/body elements -->
    <xsl:template match="body">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="h5">
        <!-- record the current h5 title -->
        <xsl:variable name="title" select="."/>
        <h5>
            <xsl:attribute name="title">
                <xsl:value-of select="$title" />
            </xsl:attribute>

            <xsl:for-each select="following-sibling::div[preceding-sibling::h5[1] = $title]">
                <!-- deep copy of each consecutive div following the current h5 element -->
                <xsl:copy-of select="." />
            </xsl:for-each>
        </h5>
    </xsl:template>

    <!-- match div, but do not output anything since we are copying it into the new h5 element -->
    <xsl:template match="div" />
</xsl:stylesheet>
''')

transform = etree.XSLT(xsl)
with open("doc.xml") as f:
    print(transform(etree.parse(f)), end='')

如果样式表存储在文件名 doc.xsl 中,则使用 libxml 实用程序 xsltproc 可以获得相同的结果:

xsltproc doc.xsl doc.xml

结果:

<?xml version="1.0"?>
<p>
  <h5 title="Fruits">
    <div>This is some <span attr="foo">Text</span>.</div>
    <div>Some <span>more</span> text.</div>
  </h5>
  <h5 title="Vegetables">
    <div>Yet another line <span attr="bar">of</span> text.</div>
    <div>This span will get <span attr="foo">removed</span> as well.</div>
    <div>Nested elements <span attr="foo">will <b>be</b> left</span> alone.</div>
    <div>Unless <span attr="foo">they <span attr="foo">also</span> match</span>.</div>
  </h5>
</p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 2011-11-19
    • 1970-01-01
    • 2013-07-11
    相关资源
    最近更新 更多