2009-07-23 9 views
6

저는 C#을 처음 사용하고 XmlElement와 SelectSingleNode 메서드를 사용하기 시작했습니다. XML 파일에 값 (예 : <tag>value</tag>)이 있거나 비어있을 수있는 태그 (예 : <tag></tag>)가 있습니다. 비어있는 경우 SelectSingleNode는 null을 반환합니다.C# XmlElement : SelectSingleNode는 빈 문자열에 대해 null을 반환합니까?

저는 현재 태그의 값을 잡기 위해 다음 코드를 사용하고 있습니다 :

XmlElement elem = .... 
string s = elem.SelectSingleNode("somepath").Value; 

이 코드는 분명히 빈 태그에 대한 예외를 발생시킵니다. 그러나 나를 위해 빈 태그는 유효한 값이며, 여기서 문자열의 값은 ""이 될 것으로 기대합니다.

try ... catch를 사용하여 SelectSingleNode를 호출 할 때마다 많은 양의 코드가 낭비되는 것 같습니다 (빈 필드가 많음).이를 위해 더 좋은 방법이 있다고 확신합니다.

권장 방법은 무엇입니까?

편집 : 요청에 따라

는 샘플 XML 코드는 다음과 같습니다

<Elements> 
    <Element> 
     <Name>Value</Name> 
     <Type>Value</Type> <-- may be empty 
     <Color>Value</Color> 
    </Element> 
    <Element> 
     <Name>Value</Name> 
     <Type>Value</Type> 
     <Color>Value</Color> 
    </Element> 
</Elements> 

고사 코드 :

XmlDocument doc = new XmlDocument(); 
doc.Load("name.xml"); 

foreach (XmlElement elem in doc.SelectNodes("Elements/Element")) 
{ 
    myvalue = elem.SelectSingleNode("Type/text()").Value; 
} 
+3

전체 코드 샘플을 게시 할 수 있습니까? 아니면 제공된 XML 블록과 직접적인 상관 관계가있는 것입니까? –

+0

샘플 XML을 게시 할 수 있습니까? –

+0

예, 조금 더 많은 코드 샘플과 구문 분석에 사용하는 XML이 있습니다. 이전에 SelectSingleNode를 사용했지만 언급 한 동작을 보지 못했습니다. – SolutionYogi

답변

10

샘플 코드 : 어디에 문제가

myvalue = elem.SelectSingleNode("Type/text()").Value; 

이다. 거기에 사용 된 XPath 표현은 "나에게 요소의 텍스트를 부여하십시오"라는 뜻은 아닙니다 Type. "엘리먼트 타입의 모든 자식 텍스트 노드를 나에게 준다"는 의미입니다. 그리고 비어있는 요소에는 자식 텍스트 노드가 없습니다 (XPath 문서 모델에서는 텍스트 노드를 비워 둘 수 없습니다). 노드의 텍스트 값을 가져 오려면 다음을 사용해야합니다.

myvalue = elem.SelectSingleNode("Type").InnerText; 
+0

그게 문제 였어. 감사합니다. –

+0

InnerText는 "노드와 모든 자식 노드의 연결 값"을 제공합니다. 자녀가있을 때 기대하는 본문을 얻지 못할 것입니다. 나는 (foundNode.NodeType == XmlNodeType.Element) {foundNode = foundNode.SelectSingleNode ("text()")를 검사하는 도우미를 구현했다. if foundNode == null {return ""; }} return foundNode.Value; –

1

권장되는 방법은 .NET의 새로운 XML API를 사용하는 것 (즉, LINQ to XML).

using System; 
using System.Linq; 
using System.Xml.Linq; 

class Program 
{ 
    static void Main() 
    { 
     String xml = @"<Root><Value></Value></Root>"; 

     var elements = XDocument.Parse(xml) 
      .Descendants("Value") 
      .Select(e => e.Value); 
    } 
} 
+0

LINQ to XML은 "새로운 XML API"가 아닙니다. 기존 System.Xml 네임 스페이스를 사용해야하는 이유는 분명합니다. LINQ는 해당 네임 스페이스의 클래스를 사용하는 또 다른 방법입니다. –

+0

동의하지 않음 - System.Xml.Linq에는 XML을 처리하기위한 새로운 유형의 배열이 포함되어 있습니다. XML을 사용하기위한 진정한 새로운 API입니다. –

0

어쩌면이 당신을 위해 작동합니다 : 여기

은 예입니다

string s = elem.SelectSingleNode("somepath") != null ? elem.SelectSingleNode("somepath").value : "" 
+0

그래도 작동하지만 SelectSingleNode가 두 번 실행되므로 불필요한 성능 저하가 발생합니다. – Thorarin

+1

그래, SelectSingleNode ("// blah")가되는 XML에서 누락 된 요소를 처리하는 방법은 무엇일까? innertext는 예외를 던집니까? 끝없는 3 차 연산자가 아니라고 말해주세요 ... – Fireworks

1

http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.value(VS.71).aspx

"값"반환이 있거나 노드에 의존하기 때문에, 가능성이 있습니다 노드가 널 (NULL)을 리턴 할 수있는 유형으로 해석됩니다.

다음을 사용하여 더 나을 수 있습니다

XmlElement elem = .... 
string s = elem.SelectSingleNode("somepath").InnerText; 

XMLNode.InnerText로 (또는 XmlNode.InnerXML)는 빈 문자열을 포함하는 문자열을 반환합니다. 당신이 당신의 노드가 존재합니다 확실하지 않으면 그럼 당신은 다음과 같은 작업을 수행 할 수

static string NodeValue(XmlNode node, string defaultValue) 
{ 
    if (node != null) 
     return node.Value ?? defaultValue; 

    return defaultValue; 
} 

: 실제로 XML DOM으로 괴롭 히고있을 때

+1

SelectSingleNode가 null을 반환하면 InnerText를 호출 할 아무 것도 없습니다. – Thorarin

+0

@Thorarn : 맞습니다. 질문 (및 예)은 태그가 텍스트 사이에 존재하지 않고 노드가 존재 함을 보여줍니다. 값을 확인하기 전에 Null 노드를 확인하는 것이 좋습니다. –

+0

당신은 노드 존재에 대해 옳다. 그의 설명은 SelectSingleNode가 null을 리턴하는 것에 대해 언급했다. 그러나 거기에 요소가 있다면 비어있을 수 없다. ( – Thorarin

0

, 당신의 라인을 따라 도우미 메서드를 작성할 수

string s = NodeValue(elem.SelectSingleNode("Type"), String.Empty); 

If는 코드를 읽을 수있게 해주 며 특히 여러 요소에 대해이 작업을 수행하는 경우 유용합니다.

SelectSingleNode (..)는 이 아니며은 태그가 비어 있으면 null 값을 반환합니다. 그러나 속성은 null입니다.당신은 그냥 해결하려는 경우,이 수행해야합니다

string s = elem.SelectSingleNode("Type").Value ?? String.Empty; 

편집 : 아, 당신이 사용하고/텍스트()를 실제 텍스트 노드를 선택합니다. XPath의 해당 부분을 제거 할 수 있지만 제공된 NodeValue 메서드는 여전히 작동해야합니다 (이 경우 "defaultValue"부분은 필요하지 않습니다).

+0

) 이것도 멋지게 작동한다. 노드 자체가! = Null인지 확인하십시오. 그러나 노드는 존재할 수 있으며 여전히 NodeType이 무엇인지에 따라 NULL로 node.Value를 반환합니다. –

+0

@Paige : 물론 가능합니다. XML에 대한 가정을 할 수 없다면 더 많은 점검을해야합니다. 또는 XSD에 대해 사전에 확인하십시오. 지금 null을 반환하지 않기 위해 메소드를 약간 업데이트했습니다. – Thorarin

관련 문제