2012-03-15 81 views
2

我需要压缩XML文件中的所有重复值并保留最终值(请参阅目标文件)。如何删除XML文件中的重复值并保留最后一个?

请帮助,因为我不知道我是否应该使用XSLT,Python或任何.NET API

这里是源文件:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
<cd> 
    <artist>Bob Dylan</artist> 
</cd> 
<cd> 
    <title>Hide your heart</title> 
</cd> 
<cd> 
    <title>old_value</title> 
    <title>inbetween_value</title> 
    <title>new_value</title> 
</cd> 
</catalog> 

预期目标文件:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
<cd> 
    <artist>Bob Dylan</artist> 
</cd> 
<cd> 
    <title>Hide your heart</title> 
</cd> 
<cd> 
    <title>new_value</title> 
</cd> 
</catalog> 

回答

1

有一个极其简单(没有明确的条件语句,没有轴)XSLT溶液

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output encoding="ISO-8859-1"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="cd/title[not(position() = last())]"/> 
</xsl:stylesheet> 

当此转换应用于提供的XML文档

<catalog> 
    <cd> 
     <artist>Bob Dylan</artist> 
    </cd> 
    <cd> 
     <title>Hide your heart</title> 
    </cd> 
    <cd> 
     <title>old_value</title> 
     <title>inbetween_value</title> 
     <title>new_value</title> 
    </cd> 
</catalog> 

的希望,正确的结果产生

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
    <cd> 
     <artist>Bob Dylan</artist> 
    </cd> 
    <cd> 
     <title>Hide your heart</title> 
    </cd> 
    <cd> 
     <title>new_value</title> 
    </cd> 
</catalog> 
+0

如果OP要删除所有重复或只是'title'重复目前还不清楚。我认为你的代码只适用于后者,不是吗? – Raffaele 2012-03-15 15:54:06

+0

@Raffaele:是的 - 我严格生产的OP想要的结果... – 2012-03-15 16:58:59

+0

是它完美的作品,但第一行被删除: laurentngu 2012-03-15 17:44:21

0

你可以使用任何你想要的技术。如果你的要求是“对每个cd元素,只保留重复的子元素名称的最后一个值,”这里有一个LINQ到XML解决方案,假设你有一个XDocument命名oldDoc

var scrubbedDoc = new XDocument(new XElement("catalog", 
    from cd in oldDoc.Element("catalog").Elements("cd") 
    select new XElement("cd", 
     from elementsGroupedByName in cd.Elements().ToLookup(e => e.Name) 
     select elementsGroupedByName.Last()))); 
0

,拆卸您可以将所有副本在标签名称和元素之间保留一个字典。在Python与minidom命名:

xml = """<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
<cd> 
    <artist>Bob Dylan</artist> 
</cd> 
<cd> 
    <title>Hide your heart</title> 
</cd> 
<cd> 
    <artist>Bob Dylan</artist> 
    <title>old_value</title> 
    <title>inbetween_value</title> 
    <title>new_value</title> 
    <artist>Freddie Mercury</artist> 
    <title>Don't stop me now</title> 
</cd> 
</catalog>""" 

from xml.dom import minidom 
doc = minidom.parseString(xml) 

for cd in doc.getElementsByTagName("cd"): 
    elements = {} 
    for element in cd.childNodes: 
    if element.nodeType is not minidom.Node.ELEMENT_NODE: 
     continue 
    if element.tagName in elements: 
     cd.removeChild(element) 
     print("Removed duplicated " + element.tagName) 
    elements[element.tagName] = element 

# doc.writexml(open("/path/to/file", "w")) 
1

XSLT 1个版本:

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="*"> 
<xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
</xsl:copy> 
</xsl:template> 
<xsl:template match="cd/*"> 
<xsl:if test="not(following-sibling::*[name()=name(current())])"> 
    <xsl:copy-of select="."/> 
</xsl:if> 
</xsl:template> 
</xsl:stylesheet> 
+0

是它的工作原理,感谢 – laurentngu 2012-03-15 17:42:08

相关问题