使用python

时间:2018-12-07 19:49:09

标签: xml python-3.x

我有一个自动更新的XML文件,格式为:

<entry>
  <title>Movie 1</title>
  <summary>pics/movies/3a6f22.jpg</summary>
  <link>IMDB link</link>
  <time>Fri Dec  3 03:02:05 2018</time>
</entry>
<entry>
  <title>Movie 2</title>
  <summary>pics/movies/ae4r12.jpg</summary>
  <link>IMDB link</link>
  <time>Fri Dec  3 05:34:06 2018</time>
</entry>
<entry>
  <title>Movie 1</title>
  <summary>pics/movies/3a6f22.jpg</summary>
  <link>IMDB link</link>
  <time>Sat Dec  4 12:04:06 2018</time>
</entry>
<entry>
  <title>Movie 3</title>
  <summary>pics/movies/3f44j2.jpg</summary>
  <link>IMDB link</link>
  <time>Sat Dec 4  14:04:07 2018</time>
</entry>

我想要的输出是:

<entry>
  <title>Movie 1</title>
  <summary>pics/movies/3a6f22.jpg</summary>
  <link>IMDB link</link>
  <time>Fri Dec  3 03:02:05 2018</time>
</entry>
<entry>
  <title>Movie 2</title>
  <summary>pics/movies/ae4r12.jpg</summary>
  <link>IMDB link</link>
  <time>Fri Dec  3 05:34:06 2018</time>
</entry>
<entry>
  <title>Movie 3</title>
  <summary>pics/movies/3f44j2.jpg</summary>
  <link>IMDB link</link>
  <time>Sat Dec 4  14:04:07 2018</time>
</entry>

正在被javascript和php读取,以使用CSS列出列表。我正在尝试过滤出所有重复项(例如,标题为电影1的最后一个条目)。我搜索并找到了一些我无法正常运行的xsl / xslt解决方案。我的问题是我想删除所有具有相同标题的重复条目,但是摘要,链接或时间不需要匹配。

我尝试过:

from lxml import etree

data = open('xmlparse.xsl')
xslt_content = data.read()
xslt_root = etree.XML(xslt_content)
dom = etree.parse("movies.old.xml")
transform = etree.XSLT(xslt_root)
result = transform(dom)
f = open('movies.new.xml', 'w')
f.write(str(result))
f.close()

从此.xsl提取

<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:param name="pDoc1" select="document('movies.old.xml')"/>
 <xsl:param name="pDoc2" select="document('movies.current.xml')"/>

 <xsl:template match="/">
  <xsl:apply-templates select="$pDoc1/*"/>
 </xsl:template>

 <xsl:template match="/*">
  <archive>
   <xsl:copy-of select="node()"/>
   <xsl:copy-of select="$pDoc2/*/entry[not(name = current()/*/name)]"/>
  </archive>
 </xsl:template>
</xsl:stylesheet>

但是没有效果,我的新输出文件仍然为空。

我也尝试过使用unique_everseen,但是会删除<entry></entry>之类的数据,将时间属性重新排列到文件末尾,等等。)

1 个答案:

答案 0 :(得分:1)

请考虑使用XSLT 1.0的Muenchian Method分组方法。下面的脚本和演示假定您的根节点名为 root

XSLT

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="title_key" match="entry" use="title"/>

  <xsl:template match="/root">
      <xsl:copy>
        <xsl:apply-templates select="entry[generate-id() = 
                                           generate-id(key('title_key', title)[1])]"/>
      </xsl:copy>
  </xsl:template>

    <xsl:template match="entry">
        <xsl:copy>
            <xsl:copy-of select="*"/>
        </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

XSLT Demo

Python

from lxml import etree

# LOAD XML AND XSLT
dom = etree.parse('movies_old.xml')
xsl = etree.parse('xslt_script.xsl')

# TRANSFORM XML
transform = etree.XSLT(xsl)
result = transform(dom)

# SAVE OUTPUT TO FILE
with open('movies_new.xml', 'wb') as f:
   f.write(result)