2012-09-26 2 views
11

XML 문서를 구문 분석하려고합니다. 해당 문서는 AppxManifest 파일입니다.내 노드를 검색하기 위해 XmlDocument.SelectNodes를 가져올 수 없습니다?

예 문서는 다음과 같습니다

<?xml version="1.0" encoding="utf-8"?> 
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:build="http://schemas.microsoft.com/developer/appx/2012/build" IgnorableNamespaces="build"> 
    <Identity Name="uytury" Publisher="hygj" Version="1.0.0.12" ProcessorArchitecture="neutral" /> 
    <Properties> 
    <DisplayName>jhjj</DisplayName> 
    <PublisherDisplayName>bhhjb</PublisherDisplayName> 
    <Logo>Assets\StoreLogo.png</Logo> 
    </Properties> 
    <Prerequisites> 
    <OSMinVersion>6.2.1</OSMinVersion> 
    <OSMaxVersionTested>6.2.1</OSMaxVersionTested> 
    </Prerequisites> 
    <Resources> 
    <Resource Language="EN" /> 
    </Resources> 
    <Applications> 
    <Application Id="App" Executable="gfg.exe" EntryPoint="gfg.App"> 
     <VisualElements DisplayName="fdsf" Logo="Assets\Logo.png" SmallLogo="Assets\SmallLogo.png" Description="gfdsg" ForegroundText="light" BackgroundColor="#2672EC"> 
     <DefaultTile ShowName="allLogos" WideLogo="Assets\WideLogo.png" ShortName="gfdsg" /> 
     <SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#2672EC" /> 
     <InitialRotationPreference> 
      <Rotation Preference="portrait" /> 
      <Rotation Preference="landscape" /> 
      <Rotation Preference="portraitFlipped" /> 
      <Rotation Preference="landscapeFlipped" /> 
     </InitialRotationPreference> 
     </VisualElements> 
     <Extensions> 
     <Extension Category="windows.search" /> 
     <Extension Category="windows.shareTarget"> 
      <ShareTarget> 
      <DataFormat>Text</DataFormat> 
      </ShareTarget> 
     </Extension> 
     </Extensions> 
    </Application> 
    </Applications> 
    <build:Metadata> 
    <build:Item Name="TargetFrameworkMoniker" Value=".NETCore,Version=v4.5" /> 
    <build:Item Name="VisualStudio" Version="11.0" /> 
    <build:Item Name="OperatingSystem" Version="6.2.9200.16384 (win8_rtm.120725-1247)" /> 
    <build:Item Name="Microsoft.Build.AppxPackage.dll" Version="11.0.50727.1" /> 
    <build:Item Name="Microsoft.Windows.UI.Xaml.Build.Tasks.dll" Version="11.0.50727.1" /> 
    </build:Metadata> 
</Package> 

나는과 같이 구문 분석하려고 :

var xml=new XmlDocument(); 
xml.Load(myfile); 
var mgr=new XmlNamespaceManager(xml.NameTable); 
mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest"); 
var nodes=xml.SelectNodes("Applications"); 

그러나, 나는이를 실행 한 후, nodes 아무것도 포함하지 않습니다. xml 문서가로드됩니다. SelectNodes("//*")을 사용하면 모든 노드가 예상대로 반환됩니다. 내 문제는 뭐지?

나는 또한

아무것도 비록 단일 노드를 검색하기 위해 나타납니다

  • Applications/*/Package/Applications/Application
  • Applications/Application
    • 으로 그 XPath 쿼리에 많은 변화를 시도했습니다. 이상적으로 노드에 Application 노드가 모두 포함되도록하고 싶습니다.

  • +2

    제목은 XDocument에 대해 이야기하지만 코드는 XmlDocument를 사용합니다. LINQ to XML을 실제로 사용했다면 Descendants ... LINQ to XML 옵션을 사용하는 것이 좋습니다. –

    +0

    @JonSkeet 안타깝게도 .Net 2.0을 대상으로하기 때문에 XML에 Linq를 사용할 수 없습니다. 그러나 나는 XmlDocument를 넣으려고했다. 나는 항상 두 가지를 혼동합니다. – Earlz

    답변

    27

    xml 네임 스페이스를 특별히 선택해야합니다. 이 코드는 잘 작동 할 수 있습니다 귀하의 경우

    "//*[local-name()='Applications']/*[local-name()='Application']"  
    

    을 고려

     var doc = new XmlDocument(); 
         doc.LoadXml(xml); 
         var nsmgr = new XmlNamespaceManager(doc.NameTable); 
         nsmgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest"); 
         var nodes = doc.SelectNodes("//a:Applications/a:Application",nsmgr); 
    
    +0

    처음에는 "표현식을 노드 집합으로 평가해야합니다" – Earlz

    +0

    업데이트 된 샘플 - 누락되었습니다. * – aiodintsov

    +0

    아, 이제 작동합니다. 우연히 이것을하는 더 깨끗한 방법이 있을까요? 나는 XPath 네임 스페이스를 한번도 다루지 않았기 때문에'/ Applications/Application'과 같이 단순하고 깨끗한 것을 사용하고 있습니다. – Earlz

    2

    당신은 읽을 필요가 있습니다이

    여기에 코드가있다 :

    var xml = new XmlDocument(); 
    xml.Load("myXMLFile1.xml"); 
    var mgr = new XmlNamespaceManager(xml.NameTable); 
    mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest"); 
    XmlNode root = xml.DocumentElement; 
    var nodes = root.SelectNodes("//*[local-name()='Applications']/*[local-name()='Application']"); 
    
    +0

    나는 그것을 읽었습니다 :) 네임 스페이스가없는 XML 파일과 비교했을 때 XPath 쿼리가 근본적으로 XPath 쿼리를 변경한다는 것을 깨닫지 못했습니다. – Earlz

    7

    NamespaceManager 및 XPath에서 네임 스페이스 접두사를 지정해야합니다. 접두어는 XPath와 네임 스페이스 관리자 * 사이를 제외하고는 어떤 것도 일치 할 필요가 없습니다.

    var xml=new XmlDocument(); 
    xml.Load(myfile); 
    var mgr=new XmlNamespaceManager(xml.NameTable); 
    mgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest"); 
    mgr.AddNamespace("bar", "http://schemas.microsoft.com/developer/appx/2012/build"); 
    var nodes=xml.SelectNodes("//a:Applications", mgr); 
    

    다른 답변에 의해 지적 된대로 네임 스페이스를 허용하는 XPath는 다른 옵션입니다.

    *) 즉, 특정 샘플에는 "default"라는 두 개의 네임 스페이스가 있습니다 (기본 접두사는 빈 네임 스페이스와 같지 않습니다). 따라서 네임 스페이스 관리자를 정의 할 때 각 네임 스페이스에 접두사를 지정해야합니다 (양쪽 모두에서 노드를 대상으로해야하는 경우). 그러나 접두사는 임의의 문자열이 될 수 있습니다 (접두사에는 유효 하나 비어는 없습니다). 나는. "기본"네임 스페이스에 "a"를 사용하고 XML에서 "빌드"에 매핑 된 네임 스페이스에 "바"를 사용하십시오.

    +0

    Heh, 이상합니다. 이 코드를 사용하면 "Namespace Manager 또는 XsltContext가 필요합니다.이 쿼리에는 접두사, 변수 또는 사용자 정의 함수가 있습니다"는 네임 스페이스 관리자가 있어도별로 이해가되지 않습니까? – Earlz

    +1

    그 노드가 루트 바로 아래에 있지 않기 때문에 나는'// a : Applications' 또는'a : Package/a : Applications'라고 생각합니다. – MiMo

    +1

    네임 스페이스 관리자는'SelectNodes'에 전달되어야합니다 : SelectNodes ("// a : Applications", mgr);' – MiMo

    0

    실제 XML의 네임 스페이스 URN이 네임 스페이스 관리자에 네임 스페이스를 추가하는 데 사용 된 네임 스페이스 URN과 정확히 일치하지 않는 경우 (예 : 후행 슬래시가 누락 된 경우) 및 접두사 XPath에 지정된 경우 쿼리에서 null을 반환 할 수 있습니다.

    는 XML의 네임 스페이스 URN은 신뢰할 수없는 경우, 구문

    "//*[local-name()='tag']" 
    

    가 작동합니다.

    관련 문제