2009-04-20 5 views
10

기본 요구 사항은 XML 파일에서 요소 값을 가져 오는 것입니다. XMLDoxument.SelectSingleNode를 사용했습니다. XML 파일에 헤더에 일부 Namespace이 포함되어 있으므로 NameSpaceManager를 사용하여 namespace-prefix를 추가했으며 해당 특정 요소를 가져 오기 위해 접두사를 사용했습니다. 이제 네임 스페이스가 다양 해지는 XML 파일에서 하드 코딩을하고 싶지는 않습니다. 모든 네임 스페이스를 찾을 수 있고 NameSpaceManager에 추가 할 수있는 방법이 있습니까?XML에서 모든 네임 스페이스를 어떻게 나열 할 수 있습니까?

감사합니다.

+0

@Ruchita :이 접근법의 문제점은 네임 스페이스 선언을 덮어 쓸 수 있다는 것입니다. (XML 1.0에서는 XML 1에서 기본 네임 스페이스 선언을 다시 설정할 수도 있습니다.1 모든 네임 스페이스 선언) –

답변

2

XmlDocument에서 네임 스페이스를 검색하는 기본적인 문제는 XmlDocument의 NameTable을 검색하여 XmlNameSpaceManager을 만드는 것만으로 해결할 수 있습니다.

그러나 다른 목적으로 네임 스페이스를 나열하려면 XPathNavigator 클래스뿐만 아니라 XmlNamespaceManager 클래스로 노출되는 GetNamespacesInScope 메서드를 확인해야합니다.

XmlDocument를 사용하는 경우, 다음과 같은 코드를 통해에서있는 XmlNamespaceManager를 얻을 수

:

//Instantiate an XmlDocument object. 
XmlDocument xmldoc = new XmlDocument(); 

//Load XML file into the XmlDocument object. 
xmldoc.Load("C:\\myFile.xml"); 

//Instantiate an XmlNamespaceManager object. 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable); 

// Retrieve the namespaces into a Generic dictionary with string keys. 
IDictionary<string, string> dic = nsMgr.GetNamespacesInScope(XmlNamespaceScope.All); 

// Iterate through the dictionary. 

... 

In this article가, 스콧 Hanselman은이 XPathNavigator를 사용하여 문서의 모든 네임 스페이스를 나열하려면이 방법을 사용하는 방법을 제시하고, LINQ 브리지를 사용합니다. 귀하의 빠른 응답에 대한

+2

이것은 나를 위해 작동하지 않습니다. 문서의 NameTable에는 많은 항목이 있지만 문서의 시작 부분에 정의 된 여러 네임 스페이스가 XmlNamespaceManager에 추가되지 않습니다. 네임 스페이스를 수동으로 관리자에 추가하지 않으면 SelectNodes 호출에서 "Namespace not defined"가 계속 나타납니다. XML 문서에 정의 된 네임 스페이스를 정확하게 읽는 솔루션이 필요하며이를 네임 스페이스 관리자에 추가하므로 코드를 하드 코딩 할 필요가 없습니다. –

+0

@SeanWorle 조금 늦었지 만 [XPathDocument 및 LINQ to XML을 사용하여 XML 문서의 네임 스페이스 가져 오기] (http://www.hanselman.com/blog/CommentView.aspx?guid=51861b63-526f-4572- ba84-2f24a1c7bd83) 아마 당신이나 다른 사람을 도울 수 있습니다. – ErikE

+1

이 방법의 문제점은 "xmlns"항목을 무시한다는 것입니다. –

7

덕분에 ...

난 당신이 한 최신해야합니다 사용하는 닷넷 버전을 생각합니다. 나는 그 때까지는 닷넷 프레임 워크 :(... 꽤 오래된 1.1 ..

을 사용하고 ,, 난 ...

XmlNodeList _xmlNameSpaceList = _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]"); 

      _xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);   

      foreach(XmlNode nsNode in _xmlNameSpaceList) 
      { 
       _xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value); 
      } 

하나를 동일한 목적을 위해이 같은 일부 샘플 코드 ...를 가지고있다 코멘트는 내 KB에 대한 지식을 추가하는 것으로 평가 될 것입니다 ... 감사합니다

+0

좋은 오래된 XPath는 완벽하게 작동하며 네임 스페이스가있는 모든 노드를 검색합니다. 감사 – zulucoda

-2

네임 스페이스 문제를 피하기 위해 빠른 방법을 찾고 있다면 XmlDocument를하기 전에 RegEx를 통해 네임 스페이스 정의를 XML에서 제거하십시오 .LoadXml (bla). 라이브 XHTML 페이지를 구문 분석 할 때이 작업을 수행합니다 .XmlDoc로드 시간을 15 초에서 .15 초까지 가져 와서 xpaths 접두사를 사용할 필요가 없도록 만듭니다. .

13

네임 스페이스는 XML 문서의 어느 위치에서나 찾을 수 있습니다. 그래서 모든 네임 스페이스를 추출하고 난 다음했던있는 XmlNamespaceManager로 선언합니다 :

public static XmlNamespaceManager getAllNamespaces(XmlDocument xDoc) 
{ 
    XmlNamespaceManager result = new XmlNamespaceManager(xDoc.NameTable); 

    IDictionary<string, string> localNamespaces = null; 
    XPathNavigator xNav = xDoc.CreateNavigator(); 
    while (xNav.MoveToFollowing(XPathNodeType.Element)) 
    { 
     localNamespaces = xNav.GetNamespacesInScope(XmlNamespaceScope.Local); 
     foreach (var localNamespace in localNamespaces) 
     { 
      string prefix = localNamespace.Key; 
      if (string.IsNullOrEmpty(prefix)) 
        prefix = "DEFAULT"; 

      result.AddNamespace(prefix, localNamespace.Value); 
     } 
    } 

    return result; 
} 

그냥 기본 네임 스페이스의 경우에주의를 기울이십시오. 기본 네임 스페이스를 쿼리 할 때 위의 반환 된 네임 스페이스 관리자를 사용하여 SelectSingleNode를 만들 때 문제가 발생하여 기본 네임 스페이스를 "DEFAULT"접두사로 다시 정의했습니다. 나는 그 해결 방법이었다. 희망이 있습니다

0

루치타는 XmlDocument에 대한 작업 솔루션을 게시했습니다. 그러나 나는 XDocument와 동일하게하고 싶었다. 여기 XDocument와 매우 동일합니다

지금
var xml = XDocument.Load(filename); 
var xmlNameSpaceList = ((IEnumerable)xml.XPathEvaluate(@"//namespace::*[not(. = ../../namespace::*)]")).Cast<XAttribute>(); 
var xmlNSmgr = new XmlNamespaceManager(new NameTable()); 
foreach (var nsNode in xmlNameSpaceList) 
{ 
    xmlNSmgr.AddNamespace(nsNode.Name.LocalName, nsNode.Value); 
} 

당신은 예를 들어, 네임 스페이스와 XPath를 사용할 수 있습니다 xml.XPathEvaluate("//test:p", xmlNSmgr).

관련 문제