2010-04-07 7 views
6

Location 값이있는 항목을 선택하는 데 XPath를 사용하려고하지만 현재 모든 항목을 선택하려고 시도하고 있습니다. 시스템에서 행복하게 0 개 항목을 발견했다고보고합니다. 반환합니다 (대신 노드는 foreach 루프로 처리되어야 함). 원래의 쿼리를 작성하거나 XPath를 사용하는 데 도움을 주셔서 감사합니다.C# XPath 무엇이든 찾지 못함

XML

<?xml version="1.0" encoding="UTF-8" ?> 
<Collection Name="My Collection" SchemaVersion="1.0" xmlns="http://schemas.microsoft.com/collection/metadata/2009" xmlns:p="http://schemas.microsoft.com/livelabs/pivot/collection/2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<FacetCategories> 
    <FacetCategory Name="Current Address" Type="Location"/> 
    <FacetCategory Name="Previous Addresses" Type="Location" /> 
</FacetCategories> 
    <Items> 
     <Item Id="1" Name="John Doe"> 
      <Facets> 
       <Facet Name="Current Address"> 
        <Location Value="101 America Rd, A Dorm Rm 000, Chapel Hill, NC 27514" /> 
       </Facet> 
       <Facet Name="Previous Addresses"> 
        <Location Value="123 Anywhere Ln, Darien, CT 06820" /> 
        <Location Value="000 Foobar Rd, Cary, NC 27519" /> 
       </Facet> 
      </Facets> 
     </Item> 
    </Items> 
</Collection> 

C#

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 
    XmlNodeList xnl = root.SelectNodes("//Item"); 
    Console.WriteLine(String.Format("Found {0} items" , xnl.Count)); 
} 

이 이보다 방법에 대한 더 많은,하지만 이것이 내가 믿고있어 실행됩니다 모든 것을이기 때문에 문제가 여기에있다. root.ChildNodes을 호출하면 FacetCategoriesItems을 정확하게 반환하므로 완전히 손실됩니다.

도움 주셔서 감사합니다.

답변

17

루트 요소에 네임 스페이스가 있습니다. 네임 스페이스 해석자를 추가하고 쿼리의 요소 앞에 접두사를 추가해야합니다.

This article은 해결책을 설명합니다. 1 개의 결과를 얻도록 코드를 수정했습니다.

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 

    // create ns manager 
    XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(document.NameTable); 
    xmlnsManager.AddNamespace("def", "http://schemas.microsoft.com/collection/metadata/2009"); 

    // use ns manager 
    XmlNodeList xnl = root.SelectNodes("//def:Item", xmlnsManager); 
    Response.Write(String.Format("Found {0} items" , xnl.Count)); 
} 
6

당신이 당신의 루트 노드에 XML 네임 스페이스를 가지고 있기 때문에, 당신의 XML 문서에서 "항목"같은 건 없습니다 만 "[네임 스페이스] : 항목", 그래서 XPath를 가진 노드를 검색 할 때, 네임 스페이스를 지정해야합니다.

마음에 들지 않으면 local-name() 함수를 사용하여 로컬 이름 (접두사 이외의 이름 부분)이 원하는 값과 일치하는 모든 요소를 ​​일치시킬 수 있습니다. 약간 추한 구문이지만 작동합니다.

XmlNodeList xnl = root.SelectNodes("//*[local-name()='Item']"); 
관련 문제