2013-04-15 5 views
-1

예 : endtag를 읽을 수있는 방법이 있습니까? XMLDocument 클래스를 사용합니다. 일부 제한으로 인해 XmlREader 또는 XmlTextReader를 사용할 수 없습니다. MSDN에서는 XmlNodeType.EndElement를 XMLReader MSDN link과 함께 사용할 수 있다고 언급합니다. 내 코드는 다음과 같은 것입니다 :C에서 XmlDocument 클래스를 사용하여 종료 태그 읽기 #

XmlDocument doc = functionWhichReturnsXmlDoc(); 
XmlNodeList nodes =textDoc.ChildNodes; 
foreach (XmlNode node in nodes) 
{ 
switch (node.NodeType) 
    { 
    case XmlNodeType.Element: 
    XmlNodeList nodes =textDoc.ChildNodes; 
      switch (node.NodeType) 
      { 
       case XmlNodeType.Element: 
        //do something 
       case XmlNodeType.Text: 
        //do something 
       case XmlNodeType.EndElement: 
       // THIS EVER EXECUTES 
      } 
     } 
} 

내 XML 파일 "나는 문자열의 목록으로 출력을 얻기 위해 노력하고 무엇

<Text > 
<environment> 
    <Tempratue> 
     <element id="COLD">Cold</element> 
     <element id="MILd">Mild</element> 
     <element id="HOT">Hot</element> 
    </Tempratue> 
     <element id = "Windy">true</element> 
</environment> 
<dish> 
<element id = "dish1">1111</element> 
<element id = "dish2">2222</element> 
</dish> 

</Text> 

: - 사전에

/Text/Environment/Temprature/COLD 
/Text/Environment/Temprature/MILD 
/Text/Environment/Temprature/HOT 
/Text/Environment/Windy 
/Text/dish/dish1 
/Text/dish/dish2 

감사합니다 .

--AAT

+1

닫는 태그에서 검색하려는 정보는 무엇입니까? 여기에 귀하의 문제가 무엇인지 명확하지 않습니다. – 48klocs

+0

다음과 같이 태그 이름과 ID가 인 문자열을 만들려고합니다./Text/Temprature/COLD 또는/Text/Temprature/HOT .. – AAT

+0

왜 닫는 태그를 감지해야합니까? 그렇게? ''경로의리스트를 생성하고 싶습니까, 아니면 그것보다 복잡합니까? – JLRishe

답변

4

나는 당신의 알고리즘이 어떻게 작동 하는지를 확신하지 못했지만, 당신이 잘못된 방향으로 가고 있다고 확신한다.

/Text/environment/Tempratue/COLD 
/Text/environment/Tempratue/MILd 
/Text/environment/Tempratue/HOT 
/Text/environment/Windy 
/Text/dish/dish1 
/Text/dish/dish2 
:

internal static List<string> BuildPaths(XmlDocument doc) 
{ 
    List<string> paths = new List<string>(); 

    BuildPaths(doc.DocumentElement, paths); 

    return paths; 
} 

private static void BuildPaths(XmlNode node, List<string> paths, string prefix = "/") 
{ 
    if (node.Name == "element") 
    { 
     // end case - elements named "element" 
     paths.Add(prefix + node.Attributes["id"].Value); 
    } 
    else 
    { 
     // iterate through child nodes that are either not named element or that 
     // have an attribute named "id" (i.e. skip elements named "element" that 
     // lack an id attribute) 
     foreach (XmlNode child in node.SelectNodes("*[not(self::element) or @id]")) 
     { 
      BuildPaths(child, paths, prefix + node.Name + "/"); 
     } 
    } 
} 

을이 샘플 XML을 실행하면 결과는 다음 문자열의 목록입니다 : 이것은 당신이 설명한 경로의 목록을 제공 할 수있는 하나의 방법입니다

그리고 함수 프로그래밍 원리를 따르기 때문에 조금 더 좋아 보이는 접근법이 있습니다. 이 경우 위의 첫 번째 BuildPaths() 메서드는 필요하지 않습니다.

private static List<string> BuildPaths(XmlNode node, string prefix = "/") 
{ 
    // Get child node if current node is the root 
    if (node.NodeType == XmlNodeType.Document) { node = node.FirstChild; } 

    if (node.Name == "element") 
    { 
     return new List<string> { prefix + node.Attributes["id"].Value }; 
    } 
    else 
    { 
     return node.SelectNodes("*[not(self::element) or @id]") 
        .OfType<XmlNode>() 
        .Select(n => BuildPaths(n, prefix + node.Name + "/")) 
        .SelectMany(l => l) 
        .ToList(); 
    } 
} 
+0

감사합니다. 그것은 나를 위해 일했습니다. – AAT

0

EndElement 노드를 감지하는 대신 단순히 반대로 작업하십시오. 경로 정보를 자신이 어디에 있는지 알 수있는 방식으로 저장 한 다음 경로를 밖으로부터 차례로 인쇄 할 수 있습니다.

List<string> 또는 StringBuilder 중 하나를 사용하면 목록을 더 쉽게 조작 할 수 있습니다. 새 하위 노드 그룹을 입력 할 때 인쇄 할 문자열을 저장하고 원하는대로 노드 이름이나 속성 값을 추가 한 다음 목록을 올바르게 해석하는 출력 기능을 작성하십시오.