3

我有一个程序每天生成一个大的 xml,我想节省空间,并且有些信息在一段时间后没有用。我想删除这些信息,例如我的 xml 现在是:

<owner name="thename">
   <datasets ndatasets="10" size="10000">
       <dataset size="100" creationdate="...">mydataset1</dataset>
       <dataset size="200" creationdate="...">mydataset2</dataset>
       ...
   </datasets>
</owner>
<owner name="thename2">
  ...
</owner>

我想删除单个数据集上的信息,所以我想将其转换为:

<owner name="thename">
   <datasets ndatasets="10" size="10000" />
</owner>
<owner name="thename2">
  ...
</owner>

最简单的方法是什么?我正在使用 python,但也欢迎使用其他简单且可移植的解决方案

4

3 回答 3

4

一个 XSLT 解决方案dataset(Sean 的解决方案很好,但如果其他元素或节点成为 的子节点,它将停止工作datasets):

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

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
 <xsl:template match="datasets/node()"/>
</xsl:stylesheet>

当此转换应用于提供的骨架 XML(包装到单个顶部元素中以使其成为格式良好的 XML 文档)时:

<t>
    <owner name="thename">
        <datasets ndatasets="10" size="10000">
            <dataset size="100" creationdate="...">mydataset1</dataset>
            <dataset size="200" creationdate="...">mydataset2</dataset>
        </datasets>
    </owner>
    <owner name="thename2">
        <datasets ndatasets="10" size="10000">
            <dataset size="100" creationdate="...">mydataset1</dataset>
            <dataset size="200" creationdate="...">mydataset2</dataset>
        </datasets>
    </owner>
</t>

产生了想要的正确结果:

<t>
   <owner name="thename">
      <datasets ndatasets="10" size="10000"/>
   </owner>
   <owner name="thename2">
      <datasets ndatasets="10" size="10000"/>
   </owner>
</t>

说明

正确使用标识规则并使用匹配任何子节点的空体模板覆盖它datasets

于 2012-06-19T12:24:03.640 回答
4

这是一个 XSLT 1.0 样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="node()|@*">
 <xsl:copy>
  <xsl:apply-templates select="node()|@*"/>
 </xsl:copy>
</xsl:template>

<xsl:template match="dataset" />

</xsl:stylesheet>

这里有几个提示可以帮助您开始 XSLT 之旅:

于 2012-06-19T07:29:46.227 回答
2

我认为@Sean B. Durkin 的答案更简单,但如果你想用以下方法来做这件事lxml

from lxml import etree
from StringIO import StringIO

xml = etree.parse(StringIO('''<owner name="thename">
      <datasets ndatasets="10" size="10000">
        <dataset size="100" creationdate="...">mydataset1</dataset>
        <dataset size="200" creationdate="...">mydataset2</dataset>
      </datasets>
      </owner>'''))

[d.getparent().remove(d) for d in  xml.findall('.//dataset')]
print etree.tostring(xml, pretty_print=True)

结果:

<owner name="thename">
<datasets ndatasets="10" size="10000">
   </datasets>
</owner>
于 2012-06-19T07:38:15.787 回答