2013-04-15 12 views
5

Obecnie robię niektóre parsowanie bardzo dużych plików xml> 40 MB. Właśnie zacząłem rozwijać w scala, więc przeglądałem sieć dla dobrych bibliotek i natknąłem się na Scala Scales, która wydaje się być bardzo dobra w obsłudze dużych plików.Gdzie można znaleźć przykłady kodu Scales Xml

Znam: http://scala-scales.googlecode.com/svn/sites/scales/scales-xml_2.9.1/0.2/ScalesXmlIntro.html , http://scala-scales.googlecode.com/svn/sites/scales/scales-xml_2.9.2/0.4.4/PullParsing.html

a następnie zbadano funkcję pullXml, aby upewnić się, że wszystkie libs są importowane poprawnie.

val pull = pullXml(new FileReader("/Users/mycrazyxml/tmp/large.xml")) 
while(pull.hasNext){ 
    pull.next match { 
     case Left(i : XmlItem) => 
      // Handle XmlItem 
      Logger.info("XmlItem: "+i) 

     case Left(e : Elem) => { 
      // Handle Element 
      Logger.info("Element: "+e) 
     } 

     case Right(endElem) => 
      // Handle endElement 
      Logger.info("Endelement: "+endElem)   
     } 
    } 

Powoduje to, że cały plik zostanie wydrukowany na konsoli! Miły! Teraz nadszedł czas, aby utworzyć obiekty i zapisać do bazy danych, ale mam problemy z uchwyceniem, jak to zrobić w dobry sposób. Naprawdę potrzebowałbym dobrych przykładów: , jak to zrobić.

Np. następujące XML ma kilka elementów Enterprise, które mogą składać się z jednego lub kilku LocalUnits. Chodzi o to, aby utworzyć obiekt Enterprise z tablicą LocalUnits. Kiedy endElement jest tagiem zamykającym dla przedsiębiorstwa, wywołaj metodę save z obiektem Enterprise z jego LocalUnits.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE Info SYSTEM "info.dtd"> 
<Info> 
    <Enterprise> 
    <RegNo>12345678</RegNo> 
    <Address> 
     <StreetInfo> 
     <StreetName>Infinite Loop</StreetName> 
     <StreetNumber>1</StreetNumber> 
     </StreetInfo> 
    </Address> 
    <EName> 
     <Legal>Crazy Company</Legal> 
    </EName> 
    <SNI> 
     <Code>00000</Code> 
     <Rank>1</Rank> 
    </SNI> 
    <LocalUnit> 
     <CFARNo>987654321</CFARNo> 
     <LUType>1</LUType> 
     <LUName>Crazy Company Gym</LUName> 
     <LUStatus>1</LUStatus> 
     <SNI> 
     <Code>46772</Code> 
     <Rank>1</Rank> 
     </SNI> 
     <SNI> 
     <Code>68203</Code> 
     <Rank>2</Rank> 
     </SNI> 
     <Address> 
     <StreetInfo> 
      <StreetName>Infinite Loop</StreetName> 
      <StreetNumber>1</StreetNumber> 
     </StreetInfo> 
     </Address> 
    </LocalUnit> 
    <LocalUnit> 
     <CFARNo>987654322</CFARNo> 
     <LUType>1</LUType> 
     <LUName>Crazy Company Restaurant</LUName> 
     <LUStatus>1</LUStatus> 
     <SNI> 
     <Code>46772</Code> 
     <Rank>1</Rank> 
     </SNI> 
     <SNI> 
     <Code>68203</Code> 
     <Rank>2</Rank> 
     </SNI> 
     <Address> 
     <StreetInfo> 
      <StreetName>Infinite Loop</StreetName> 
      <StreetNumber>1</StreetNumber> 
     </StreetInfo> 
     </Address> 
    </LocalUnit> 
    </Enterprise> 
<Enterprise> 
    <RegNo>12345671220</RegNo> 
    <Address> 
     <StreetInfo> 
     <StreetName>Cupertino Road</StreetName> 
     <StreetNumber>2</StreetNumber> 
     </StreetInfo> 
    </Address> 
    <EName> 
     <Legal>Fun Company HQ</Legal> 
    </EName> 
    <SNI> 
     <Code>00000</Code> 
     <Rank>1</Rank> 
    </SNI> 
    <LocalUnit> 
     <CFARNo>987654321</CFARNo> 
     <LUType>1</LUType> 
     <LUName>Fun Company</LUName> 
     <LUStatus>1</LUStatus> 
     <SNI> 
     <Code>46772</Code> 
     <Rank>1</Rank> 
     </SNI> 
     <SNI> 
     <Code>68203</Code> 
     <Rank>2</Rank> 
     </SNI> 
     <Address> 
     <StreetInfo> 
      <StreetName>Cupertino road</StreetName> 
      <StreetNumber>2</StreetNumber> 
     </StreetInfo> 
     </Address> 
    </LocalUnit>  
    </Enterprise> 
</Info> 

Podsumowując. Dla danego xml w jaki sposób mam użyć pullXml do tworzenia moich obiektów i wywołania z nimi metody zapisu?

Odpowiedz

2
val xmlFile = resource(this, "/data/enterprise_info.xml") 
val xml = pullXml(xmlFile) 

val Info = NoNamespaceQName("Info") 
val Enterprise = NoNamespaceQName("Enterprise") 
val LocalUnit = NoNamespaceQName("LocalUnit") 
val LocalUnitName = NoNamespaceQName("LUName") 
val EName = NoNamespaceQName("EName") 
val Legal = NoNamespaceQName("Legal") 

val EnterprisePath = List(Info, Enterprise) 

// iterate over each Enterprise 
// only an Enterprise at a time is in memory 
val itr = iterate(EnterprisePath, xml) 

for { 
    enterprise <- itr 
    enterpriseName <- enterprise \* EName \* Legal 
} { 
    println("enterprise "+text(enterpriseName) +" has units:") 
    for { 
    localUnits <- enterprise \* LocalUnit 
    localName <- localUnits \* LocalUnitName 
    }{ 
    println(" " + text(localName)) 
    } 
    //do a save 
} 

Ciągnięcie w każdym LocalUnit leniwie jest trudniejsze w tej chwili, trzeba oddzielne ścieżki dla każdej podsekcji, które nie jest LocalUnit.

Hth

+0

Dziękujemy! Właśnie tego szukałem! metoda text() to coś, co zadeklarowałeś sam lub czy jest to metoda pomocnicza w skalach? Moja idea nie może znaleźć importu. – jakob

+1

Ok znalazł to xpath.Functions.text(). Hmm, dlaczego mój pomysł nie rozwiązuje tego problemu? – jakob

Powiązane problemy