我有一个程序每天生成一个大的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,但也欢迎其他简单易用的解决方案
答案 0 :(得分: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之旅的指示:
答案 1 :(得分:4)
一个XSLT解决方案(Sean的解决方案很好,但是如果dataset
以外的元素或节点成为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
的任何子节点匹配的空体模板覆盖它。
答案 2 :(得分: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>