2013-07-23 5 views
0

제 3 자의 XML 파일이 있습니다. XML 파일이 큰 (40메가바이트)이기 때문에,이 방법으로 사용하여 XmlTextReader를 사용 단계에서 파일 단계를 분석하고 있습니다 :XmlTextReader, 같은 이름의 자식이있는 노드 건너 뛰기

class Parser 
{ 
    // ... 

    public void ImportFile(string fileName) 
    { 
     bool isCountryStateFile = IsCountryStateFile(fileName); 

     XmlTextReader xmlReader = new XmlTextReader(fileName); 
     namespaceManager = new XmlNamespaceManager(xmlReader.NameTable); 
     namespaceManager.FillRuianNamespaces(); 

     xmlReader.WhitespaceHandling = WhitespaceHandling.None; 

     while (xmlReader.Read()) 
     { 
      if (xmlReader.NodeType == XmlNodeType.Element && 
       xmlReader.IsStartElement() == true) 
      { 
       // skip items in country state file (are included in sity state files) 
       if (isCountryStateFile && nodesToSkipInCountryStateFile.Contains(xmlReader.Name)) 
       { 
        Console.WriteLine("Skiping {0}", xmlReader.Name); 
        xmlReader.Skip(); 
       } 

       if (xmlReader.Name == "vf:Vusc") 
       { 
        var item = ParseRegion(xmlReader); 
        repository.Save(item); 
        xmlReader.Skip(); 
       } 
       if (xmlReader.Name == "vf:Obec") 
       { 
        var item = ParseCity(xmlReader); 
        repository.Save(item); 
        xmlReader.Skip(); 
       } 
      } 
     } 

     xmlReader.Close(); 
    } 

    private Region ParseRegion(XmlTextReader xmlReader) 
    { 
     XmlDocument node = new XmlDocument(); 
     node.LoadXml(xmlReader.ReadOuterXml()); 

     // parse and compose Region 
     // ... 

     return result; 
    } 

    // ... 
} 

일반적으로 노드가 <Cities><City/></Cities>로 구성되어 모든 것이 잘 작동을하지만, 일부 노드는 같은 이름을 가진 자식 노드가 포함 부모 :

<?xml version="1.0" encoding="UTF-8"?> 
<vf:VymennyFormat xsi:schemaLocation="urn:cz:isvs:ruian:schemas:VymennyFormatTypy:v1 ../ruian/xsd/vymenny_format/VymennyFormatTypy.xsd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ami="urn:cz:isvs:ruian:schemas:AdrMistoIntTypy:v1" xmlns:base="urn:cz:isvs:ruian:schemas:BaseTypy:v1" xmlns:coi="urn:cz:isvs:ruian:schemas:CastObceIntTypy:v1" xmlns:com="urn:cz:isvs:ruian:schemas:CommonTypy:v1" xmlns:kui="urn:cz:isvs:ruian:schemas:KatUzIntTypy:v1" xmlns:kri="urn:cz:isvs:ruian:schemas:KrajIntTypy:v1" xmlns:mci="urn:cz:isvs:ruian:schemas:MomcIntTypy:v1" xmlns:mpi="urn:cz:isvs:ruian:schemas:MopIntTypy:v1" xmlns:obi="urn:cz:isvs:ruian:schemas:ObecIntTypy:v1" xmlns:oki="urn:cz:isvs:ruian:schemas:OkresIntTypy:v1" xmlns:opi="urn:cz:isvs:ruian:schemas:OrpIntTypy:v1" xmlns:pai="urn:cz:isvs:ruian:schemas:ParcelaIntTypy:v1" xmlns:pui="urn:cz:isvs:ruian:schemas:PouIntTypy:v1" xmlns:rsi="urn:cz:isvs:ruian:schemas:RegSouIntiTypy:v1" xmlns:spi="urn:cz:isvs:ruian:schemas:SpravObvIntTypy:v1" xmlns:sti="urn:cz:isvs:ruian:schemas:StatIntTypy:v1" xmlns:soi="urn:cz:isvs:ruian:schemas:StavObjIntTypy:v1" xmlns:uli="urn:cz:isvs:ruian:schemas:UliceIntTypy:v1" xmlns:vci="urn:cz:isvs:ruian:schemas:VuscIntTypy:v1" xmlns:vf="urn:cz:isvs:ruian:schemas:VymennyFormatTypy:v1" xmlns:zji="urn:cz:isvs:ruian:schemas:ZsjIntTypy:v1"> 
    <vf:Data> 
     <vf:Vusc> <!-- HERE --> 
      <vf:Vusc gml:id="VC.19"> 
       <vci:Kod>19</vci:Kod> 
       <vci:Nazev>Hlavní město Praha</vci:Nazev> 
       <vci:RegionSoudrznosti> 
        <rsi:Kod>19</rsi:Kod> 
       </vci:RegionSoudrznosti> 
       <vci:PlatiOd>2013-06-11T00:00:00</vci:PlatiOd> 
       <vci:IdTransakce>241736</vci:IdTransakce> 
       <vci:GlobalniIdNavrhuZmeny>413702</vci:GlobalniIdNavrhuZmeny> 
       <vci:NutsLau>CZ010</vci:NutsLau> 
       <vci:Geometrie> 
        <vci:DefinicniBod> 
         <gml:Point gml:id="DVC.19" srsName="urn:ogc:def:crs:EPSG::5514" srsDimension="2"> 
          <gml:pos>-743100.00 -1043300.00</gml:pos> 
         </gml:Point> 
        </vci:DefinicniBod> 
       </vci:Geometrie> 
      </vf:Vusc> 
     </vf:Vusc> 
     ... 
    </vf:Data> 
</vf:VymennyFormat> 

어떻게 이러한 상황에서 외아들 방법 XmlTextReader.Skip를 사용하는 구문 분석에 적절한 노드를 선택할 수 있습니다()는 모든 아이들과 함께 최고 수준의 같은 부모 노드를 건너 뛰려면? 내가 그걸 건너 뛰면 어쨌든 아이들을 읽는다.

+0

영역이 vf : Vusc 요소로 시작하는지 ParseRegion에서 확인할 수 있습니다.이 경우 재귀 적으로 자식 노드로 자신을 호출하십시오. –

+1

참고로, new XmlTextReader() 또는 new XmlTextWriter()를 사용하지 말아야합니다. NET 2.0부터는 사용되지 않습니다. 대신'XmlReader.Create()'또는'XmlWriter.Create()'를 사용하십시오. –

+0

@ John Saunders documentacion (http://msdn.microsoft.com/en-us/library/System.Xml.XmlTextReader.aspx)이나 컴파일러 공지에서 이에 대한 언급이 없습니다. 보여 주시겠습니까? 어디에서 찾았습니까? – Fanda

답변

2

XmlReader.ReadSubTree을 사용하여이 문제를 해결할 수 있습니다. 예를 들면 : XML의

if (xmlReader.Name == "vf:Vusc") 
{ 
    using (var subtree = xmlReader.ReadSubTree()) 
    { 
     var item = ParseRegion(subtree); 
     repository.Save(item); 
    } 
} 

ReadSubTree 한계에 얼마나 많은 ParseRegion 볼 수 있습니다. ParseRegion이 반환되면 리더는 태그의 끝 요소에 위치하게됩니다. 따라서 기본 리더 루프는 내부 ​​"vf : Vusc"태그를 보지 않습니다.