2012-03-15 4 views
2

XML 파일의 모든 중복 값을 억제하고 최종 값을 유지해야합니다 (대상 파일 참조).XML 파일에서 중복 값을 제거하고 마지막 값을 유지하는 방법은 무엇입니까?

<?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> 

예상되는 대상 파일 :

친절하게 내가 XSLT, 파이썬, 또는 모든 .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>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

영업 이익이 모두 중복 또는 단지'title' 중복을 제거하고 싶은 경우는 불분명하다. 나는 당신의 코드가 후자에 대해서만 작동한다고 생각하지 않습니까? – Raffaele

+0

@Raffaele : 예 - OP가 원하는 결과를 엄격하게 생산하고 있습니다 ... –

+0

예 완벽하게 작동하지만 첫 번째 줄이 제거되었습니다. laurentngu

0

원하는 기술을 사용할 수 있습니다. 당신이 할 수있는 모든 중복을 제거하기위한

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

: 귀하의 요구 사항 인 경우 여기에 XML 솔루션에 LINQ 당신이라는 XDocumentoldDoc이 가정의 "각 cd 요소에 대해 중복 자식 요소 이름에 대한 마지막 값을 유지" 태그 이름과 요소 사이에 dict를 유지하십시오.

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 개 버전 : minidom 파이썬에서

<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

관련 문제