2013-07-10 14 views
1

큰 XML 파일에서 XmlNodeList을 받고 싶습니다.특정 요소 값 또는 특성 값이 주어진 문자열 목록에있는 경우 XmlNodeList 가져 오기

조건 : 나는 고유 한 ID 값의 List이 IDLIST
케이스 말을 가지고 I :element라는 ID가 IDLIST에서 값을 가진 모든 노드를 수집합니다.
사례 II :attribute 중 하나 인 id가 element 인 모든 노드를 수집하여 IDList의 값을 가져옵니다.

요약하면 은 IDList에 지정된 값과 일치하는 노드 만 추출합니다.

이 XML을 XmlDocument에로드하는 것과 같은 일부 루프를 사용하여 모든 노드와 ID 값을 반복 처리했지만이 방법을 사용하면 빠르고 정교한 방법이 필요합니다. 루프가 큰 XML 파일의 솔루션이 아니기 때문에.

내 시도 :

try 
{ 
using (XmlReader reader = XmlReader.Create(URL)) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(reader); 
    XmlNodeList nodeList = doc.GetElementsByTagName("idgroup"); 
    foreach (XmlNode xn in nodeList) 
    { 
     string id = xn.Attributes["id"].Value; 
     string value = string.Empty; 
     if (IDList.Contains(id)) 
     { 
      value = xn.ChildNodes[1].ChildNodes[1].InnerText; // <value> 
      if (!string.IsNullOrEmpty(value)) 
      { 
       listValueCollection.Add(value); 
      } 
     } 
    } 
} 
} 
catch 
{} 

XML (XLIFF) 구조 :

<XLIFF> 
    <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2"> 
     <file date="2013-07-17"> 
       <body> 
        <id idName="test_001" > 
         <desc-group name="test_001"> 
           <desc type="text"/> 
         </desc-group> 
         <result-unit idName="test_001_text"> 
           <source>abcd</source> 
           <result>xyz</result> 
         </result-unit> 
        </id> 
      </body> 
     </file> 
</xliff> 
이 idName에는 일치하는 위처럼 모든 노드를 수집합니다.

+0

첨부 한 XML 형식이 올바르지 않으며 파일 형식을 설명하지 않습니다. 또한 XLIFF가 무엇을 의미하는지 알지 못하지만 예제가 이처럼 맘에 들지 않습니다. http://en.wikipedia.org/wiki/XLIFF –

+0

@Ioannis Karadimas : 감사합니다. 여기 XLIFF 구조를 업데이트했습니다. . – Indigo

+0

내 게시물을 확인하십시오. 나는 그것을 파싱 할 수있는 예제를 제공했다. –

답변

1

편집

이것은 당신이주는 예제를 구문 분석 할 수있는 테스트입니다. 이 노드는 result 노드에 직접 연결하려고 시도하므로 최대한 효율적으로 유지됩니다.

[Test] 
public void TestXPathExpression() 
{ 
    var idList = new List<string> { "test_001" }; 
    var resultsList = new List<string>(); 

    // Replace with appropriate method to open your URL. 
    using (var reader = new XmlTextReader(File.OpenRead("fixtures\\XLIFF_sample_01.xlf"))) 
    { 
     var doc = new XmlDocument(); 
     doc.Load(reader); 
     var root = doc.DocumentElement; 

     // This is necessary, since your example is namespaced. 
     var nsmgr = new XmlNamespaceManager(doc.NameTable); 
     nsmgr.AddNamespace("x", "urn:oasis:names:tc:xliff:document:1.2"); 

     // Go directly to the node from which you want the result to come from. 
     foreach (var nodes in idList 
      .Select(id => root.SelectNodes("//x:file/x:body/x:id[@idName='" + id + "']/x:result-unit/x:result", nsmgr)) 
      .Where(nodes => nodes != null && nodes.Count > 0)) 
       resultsList.AddRange(nodes.Cast<XmlNode>().Select(node => node.InnerText)); 

    } 

    // Print the resulting list. 
    resultsList.ForEach(Console.WriteLine); 
} 

당신은 당신이 XPath 쿼리를 사용하여 필요 만 노드를 추출 할 수 있습니다. 당신이 그것에 어떻게 가야하는지에 대한 간단한 예 :

using (XmlReader reader = XmlReader.Create(URL)) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(reader); 
    foreach(var id in IDList) { 
     var nodes = doc.SelectNodes("//xliff/file/body/id[@idName='" + id + "']"); 
     foreach(var node in nodes.Where(x => !string.IsNullOrEmpty(x.ChildNodes[1].ChildNodes[1].InnerText))) 
      listValueCollection.Add(node.ChildNodes[1].ChildNodes[1].InnerText); 
    } 
} 

xpath 표현은 물론 예입니다. 원한다면 XML 예제를 게시하여 좀 더 정확한 것을 제공 할 수 있습니다.

+0

고마워, 나는이 해결책을 시도 할 것이다. 질문 할 XML 노드의 구조를 추가했습니다. XPath가 정말 좋습니다. 불행히도 이전에는 사용하지 않았습니다. 시도하고 그것에 대한 자세한 정보를 얻고 싶습니다. – Indigo

+0

감사합니다, 그것은 매력처럼 작동했습니다. 나는 모든 XPath 옵션을 피곤했지만 정확한 네임 스페이스를 얻을 수 없었다. 두 번째 샘플에서는 첫 번째 샘플과 동일한 XPath가 잘 작동합니다. – Indigo