2012-07-04 6 views
2

나는 꽤 오랫동안 작업하고있다. XML 파일에 50000 개가 넘는 레코드가 있습니다 (하나의 레코드에는 3 개의 레벨이 있음). 이 파일은 내 응용 프로그램 중 하나에서 문서 전송을 제어하는 ​​데 사용됩니다 (레코드에는 다른 정보 중에서 특정 사람에게 보내야하는 문서 유형이 들어 있습니다). 그래서 내 응용 프로그램에서 XML 파일을 XmlDocument로로드 한 다음 SelectNodes 메서드를 사용하여 원하는 데이터를 읽는 XmlNodeList를 만듭니다. 과정은 이렇게 - 우리의 노동자는 사람 ID 카드 (간단한 eith 바코드)를 가지고 가고 바코드 독자로 그것을 읽는다. 바코드 값을 읽으면 내 응용 프로그램은 해당 ID를 가진 사람을 XML 파일에서 찾은 다음 문서의 유형을 문자열 변수에 저장합니다. 그런 다음 작업자가 문서를 가져 와서 바코드를 읽습니다. 문서 바코드의 값과 문자열 변수의 값이 일치하면 응용 프로그램은 xxxxxxxx 유형의 문서가 ID가 yyyyyyyyy 인 사람에게 전송된다는 레코드를 만듭니다. 이가 지금은 완벽하게 작동, 아주 간단한 코드이며,이 보이는 방법입니다 큰 XML 파일을 C#의 더 작은 조각으로 자르기

foreach(XmlNode node in NodeList){ 
if(String.Compare(node.Attributes.GetNamedItem("ID").Value.ToString(),textBox1.Text)==0) 
{ 
ControlString = node.ChildNode[3].FirstChild.Attributes.GetNamedItem("doctype").Value.ToString(); 
break; 
} 
} 
textBox2.Focus(); 

그리고 textBox2_TextChanged 이벤트에

가 (작업자가 문서에 바코드를 읽기) : textBox1_TextChanged 이벤트에 (노동자는 사람 ID를 읽기)

if(String.Compare(textBox2.Text,ControlString)==0) 
{ 
//Create a record and insert it into a SQL database 
} 

내 질문은 - 내 응용 프로그램은 XML 파일이 최대 500,000 개까지있을 수 있다고 말했지만,이 방법이 유효할까요? 작은 파일로. 전체 기록을 읽고 문자열로 저장 :

private void WriteXml(XmlNode record) 
     { 
      tempXML = record.InnerXml; 
      temp = "<" + record.Name + " code=\"" + record.Attributes.GetNamedItem("code").Value + "\">" + Environment.NewLine; 
      temp += tempXML + Environment.NewLine; 
      temp += "</" + record.Name + ">"; 
      SmallerXMLDocument += temp + Environment.NewLine; 
      temp = ""; 
      i++; 
     } 

tempXML, 온도 및 SmallerXMLDocument 나는 그것을 절단해야하는 경우, 나에게 몇 가지 코드 샘플과 아이디어를주세요,이처럼하려고 노력했습니다 모든 문자열 변수입니다.

그리고 내가 (XmlDocument.SelectNodes 방법을 사용하여 다시)를 XmlNodeList으로 XML 파일을로드하고이 같은 모든 레코드를 보유 할 하나 개의 큰 문자열 값을 만들려고 button_Click 방법에 :

foreach(XmlNode node in nodes) 
{ 
if(String.Compare(node.ChildNode[3].FirstChild.Attributes.GetNamedItem("doctype").Value.ToString(),doctype1)==0) 
{ 
    WriteXML(node); 
} 
} 

을 내 생각은 문자열 값 (이 경우 SmallerXmlDocument)을 작성하고 전체 XML 파일을 통과하면 해당 문자열의 값을 새 파일로 간단히 복사하는 것이 었습니다. 이것은 작동하지만 최대 2000 개의 레코드가있는 파일에 대해서만 가능합니다. 따라서 파일을 더 작은 조각으로 잘라야 할 경우 XML 파일에 최대 50 만 개의 레코드가있을 수 있다는 것을 명심하십시오.

감사합니다.

+0

왜 거대한 데이터에 XML을 사용하고 있습니까? SQL과 같은 DBMS를 사용하지 않는 이유는 무엇입니까? ??? – yogi

+0

불행히도, 나는 레코드를 생성하고 저장하는 회사가 아니기 때문에 클라이언트로부터 얻습니다. 그래서 지금은 XML 파일을 사용하는 것 외에는 선택의 여지가 없습니다. – NDraskovic

답변

2

먼저 XML API를 악용하는 것으로 의심됩니다. 을 직접 XPath으로 쿼리하면 레코드 목록을 먼저 선택하고 반복 할 필요없이 즉시 결과를 얻을 수 있습니다. 어떤 시점에서 XML 트리의 일부를 문자열로 변환해야 할 필요는 없습니다.

전체 XML 문서를 메모리에로드하는 방식은 응용 프로그램에 50-500MB의 RAM을 사용하는 것이 좋습니다.

RAM을 저장하려면 XmlReader을 사용하여 디스크에서 XML을 스트리밍해야합니다.

+0

XPath를 사용해 보았습니다. (이전에는 한번도 경험 해보지 못했지만) 문제는 모든 레코드의 레벨입니다. 모든 레코드에는 3 가지 레벨이 있습니다. 개인 ID는 첫 번째 레벨 (레코드의 두 번째 레벨)의 속성이며, doctype은 세 번째 레벨의 속성입니다 (따라서 자식의 자식입니다.) 사람 ID가 포함 된 노드의 이름). 특정 doctype이 어떤 doctype을 얻는 지 확인하고 싶다면 XPath가 어떻게 보이겠습니까? (SelectSingleNode 메서드에 대해 알고 있는데, XPath 쿼리에 대해 묻고 있습니다)? – NDraskovic

+1

// * [@ id = 'theid'] // * [@ doctype = 'thetype'] doctype 노드를 반환 할 것이거나 존재하지 않으면 null을 반환합니다. –

0

데이터 액세스가 필요하므로 파일 1 개가 50,000 개, 파일 수가 50 개가 될 때마다 동일한 양의 데이터가 필요합니다.

클라이언트에서 SQL-Lite 또는 SQL Server Compact를 사용하는 것을 막을 수있는 방법은 없습니다. 이것에는 많은 이점이 있습니다. XMLReader를 사용하여 DB의 테이블로 데이터를 구문 분석 할 수 있습니다. 이제 SQL 엔진을 사용하여 필요한 행을 찾고 조인을 사용하여 관련 행을 훨씬 쉽게 찾을 수 있습니다. 방대한 양의 데이터를 메모리에 저장하지 않습니다. XML이 변경 될 수있는 경우 파일 변경 사항을보고 & 때 DB를 새로 고칩니다.

+0

응용 프로그램은 한 번에 모든 파일을 읽지 않습니다. 하나의 doctype (예 : 4 개의 Doctypes가 있고 4 개의 파일이있는 경우)이있는 레코드가있는 파일을 만들고 해당 파일을 응용 프로그램에로드합니다. 이렇게하면 응용 프로그램에서로드 한 파일의 레코드 수가 약 12,000 개가되며 이는 여전히 훨씬 적습니다. SQL 사용에 관해서도이 접근법을 사용하려고 생각 했으므로 살펴 보겠습니다. 감사 – NDraskovic

관련 문제