2017-02-02 4 views
0

다음 xml 파일 (lieferungen.xml)에는 여러 불일치가 있습니다.Python SAX 파서 프로그램이 잘못된 결과를 계산합니다.

은 파일의 모든 불일치를 찾기 위해
<?xml version="1.0" encoding="UTF-8"?> 
<lieferungen xmlns="urn:myspace:lieferungen" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:myspace:lieferungen C:\xml\lieferungen.xsd"> 
    <artikel id="3526"> 
     <name>apfel</name> 
     <preis stueckpreis="true">8.97</preis> 
     <lieferant>Fa. Krause</lieferant> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <preis stueckpreis="false">10.45</preis> 
     <lieferant>Fa. Helbig</lieferant> 
    </artikel> 
    <artikel id="4444"> <!--DIFFERENT ID FOR apfel!! -->  
     <name>apfel</name> 
     <preis stueckpreis="true">12.67</preis> 
     <lieferant>Fa. Liebig</lieferant> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <preis stueckpreis="false">17.67</preis> 
     <lieferant>Fa. Krause</lieferant> 
    </artikel> 
    <artikel id="2345"> <!--DIFFERENT ID FOR apfel!! --> 
     <name>apfel</name> 
     <preis stueckpreis="true">9.54</preis> 
     <lieferant>Fa. Mertes</lieferant> 
    </artikel> 
    <artikel id="7116"> <!--DIFFERENT ID FOR Kirschen!! --> 
     <name>Kirschen</name> 
     <preis stueckpreis="false">16.45</preis> 
     <lieferant>Fa. Hoeller</lieferant> 
    </artikel> 
    <artikel id="7868"> 
     <name>Kohl</name> 
     <preis stueckpreis="false">3.20</preis> 
     <lieferant>Fa. Hoeller</lieferant> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <preis stueckpreis="false">12.45</preis> 
     <lieferant>Fa. Richard</lieferant> 
    </artikel> 
    <artikel id="3245"> 
     <name>Bananen</name> 
     <preis stueckpreis="false">15.67</preis> 
     <lieferant>Fa. Hoeller</lieferant> 
    </artikel> 
    <artikel id="6745"> <!--DIFFERENT ID FOR Kohl!! -->  
     <name>Kohl</name> 
     <preis stueckpreis="false">3.10</preis> 
     <lieferant>Fa. Reinhardt</lieferant> 
    </artikel> 
    <artikel id="7789"> 
     <name>Ananas</name> 
     <preis stueckpreis="true">8.60</preis> 
     <lieferant>Fa. Richard</lieferant> 
    </artikel> 
</lieferungen> 

, 나는 파이썬에서 다음 색소폰 파서를 썼다 : 항목 중 일부는 하나 개 이상의 ID (예 : 항목 "apfel"3 개 개의 ID를 가지고이)가

이 파일 (하나 개 이상의 ID의 발생을 표시하는 의견 주)에서 볼 수 있듯이

Inconsistencies: 

There are 3 different IDs for item "Kirschen". 

,이 출력은 두 가지 방법으로 잘못 다음과 같이

import xml.sax 
import sys 


class C_Handler(xml.sax.ContentHandler): 

    def __init__(self): 
     self.items = {} 
     self.items2 = {} 
     self.read = 0 
     self.id = 0 

    def startDocument(self): 
     print("Inconsistencies:\n") 

    def startElement(self, tag, attributes): 
     if tag=="name": 
      self.read = 1 
     if tag=="artikel": 
      self.id = attributes["id"]    

    def endElement(self, tag): 
     if tag=="name": 
      self.read = 0 

    def characters(self, content): 
     if self.read == 1: 
      item = content 
      #check whether the item is not yet part of the dictionaries 
      if item not in self.items: 
       #add item (e.g. "apfel") to both dictionary "items" and 
       #dictionary "items2". The value for the item is the id in the 
       #case of dictionary "items" and "0" in the case of dictionary 
       #"items2". The second dictionary contains the number of 
       #inconsistencies for each product. At the beginning, the 
       #number of inconsistencies for the product is zero. 
       self.items[item] = self.id 
       self.items2[item] = 0 
      else: 
       if self.items[item] == self.id: 
        #increase number of inconsistencies by 1: 
        self.items2[item] = self.items2[item] + 1 

    def endDocument(self): 
     for prod in self.items2: 
      if self.items2[prod]>0: 
       print("There are {} different IDs for item \" 
       {}\".".format(self.items2[prod] + 1, prod)) 


if (__name__ == "__main__"): 

    c = C_Handler() 
    xml.sax.parse("lieferungen.xml", c) 

이 프로그램의 출력은 다음과 같습니다

  1. "Kirschen"항목에는 3 가지가 아닌 2 가지 ID 만 있습니다. 하나 개 이상의 ID와
  2. 여러 항목이 전혀 언급되지 않은 그러나, 나는 이해가 안

를 (예를 들어, 항목 "콜 것은"두 개의 서로 다른 ID를 가지고), 내 코드에서 잘못된 무슨 일이 일어나고 있는지. Kirschen가 사용 : 내가 오해 한 않는

답변

1

, 오류가 약자로이 라인

   if self.items[item] == self.id: 

   if self.items[item] != self.id: 

을해야한다는 것입니다, 당신의 프로그램이 불일치보다는 견실함을 계산 것으로 보인다 ID 7866 세 번이나 동일한 ID를 두 번 이상 사용하지 않으므로 출력됩니다. 만든 위의 변화와

, 나는 다음과 같은 출력 얻을 :

Inconsistencies: 

There are 3 different IDs for item "apfel". 
There are 2 different IDs for item "Kirschen". 
There are 2 different IDs for item "Kohl". 

는이 말씀을 갖는, 난 당신의 코드가 반드시 당신이 시간을 모두 원하는 것을 할 것입니다 확실하지 않다. ID가 7116 인 <artikel> 요소를 다른 모든 <artikel> 요소 위로 이동 한 다음 코드를 실행 해보십시오. 당신의 코드는 Kirschen에 대해 4 개의 서로 다른 ID가 있다고 말할 것입니다.

이 이유는 항목에 대해 프로그램에서 출력하는 ID 수는 해당 항목에 대해 발견 된 첫 번째 ID에 대한 ID 수와 ID가 첫 번째 ID와 다른 ID가 다른 <artikel> 요소 각각에 대한 것입니다.

제품 당 사용되는 ID 수를 실제로 계산하려면 더 나은 방법은 세트를 사용하여 통과 할 때 각 제품에 사용 된 ID를 저장하고 더 많은 것을 포함하는 세트의 길이를 인쇄하는 것입니다 하나의 요소보다. 여기 characters 방법 변경을 한 후에 같이 볼 수 있었다 무엇 - 나는 당신의 endDocument 방법에 필요한 수정을 당신에게 그것을 떠날거야 : 마지막 줄에 내가 필요하지 않습니다

def characters(self, content): 
     if self.read == 1: 
      item = content 
      #check whether the item is not yet part of the dictionary 
      if item not in self.items: 
       self.items[item] = set([self.id]) 
      else: 
       self.items[item].add(self.id) 

주 이 이미 포함되어 있는지 확인하십시오. 집합에 대한 좋은 점은 집합에 이미있는 ID를 추가하면 아무 일도 발생하지 않는다는 것입니다.세트가 중복 ID로 끝나지 않습니다. self.items에는 필요한 모든 정보가 있으므로 더 이상 self.items2을 사용하지 않습니다.

이보다 한 단계 더 나아갈 수도 있습니다. itemself.items에 있는지 확인하고 그렇지 않은 경우 해당 항목에 대한 세트를 만들어야합니다. 만약 우리가 defaultdict을 사용한다면, 그것이 존재하지 않는다면 우리를위한 세트를 생성 할 것입니다. C_Handler 클래스 위에 from collections import defaultdict 줄을 추가하고 self.items = {} 줄을 self.items = defaultdict(set)으로 바꿉니다. 이렇게하면 characters 방법은 다음과 같아야합니다.

def characters(self, content): 
     if self.read == 1: 
      item = content 
      self.items[item].add(self.id) 
+0

대단히 감사합니다! – Tommy