web-dev-qa-db-ja.com

XmlDocument.SelectNodesを取得してノードを取得できませんか?

XMLドキュメントを解析しようとしています。問題のドキュメントはAppxManifestファイルです。

ドキュメントの例は次のようになります。

_<?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("//*")を使用すると、期待どおりにすべてのノードが返されます。ここで私の問題は何ですか?

そのようなXPathクエリの多くのバリエーションも試しました。

  • _/Package/Applications/Application_
  • _Applications/Application_
  • _Applications/*_

ただし、単一のノードを取得するようには見えません。理想的には、ノードにすべてのApplicationノードを含める必要があります

17
Earlz

それらを選択するには、特に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);
40
aiodintsov

NamespaceManagerおよびXPathsで名前空間のプレフィックスを指定する必要があります。プレフィックスは、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は別のオプションです。

*)つまり特定のサンプルには、「デフォルト」(デフォルトの接頭辞は空のネームスペースと同じではないことに注意)と「ビルド」の2つのネームスペースがあります。したがって、名前空間マネージャーを定義するときは、各名前空間の接頭辞を指定する必要があります(両方のノードを対象とする必要がある場合)。ただし、接頭辞は任意の文字列にすることができます(接頭辞には有効ですが空ではありません)。つまり「デフォルト」名前空間には「a」を使用し、XMLの「build」にマップされた名前空間には「bar」を使用します。

9
Alexei Levenkov

これを読む必要があるかもしれません

これがあなたのコードです:

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']");
4
Andreas Rehm

この特定のケースではありませんが、一般的に、実際のXMLの名前空間URNが、名前空間を名前空間マネージャーに追加するために使用されたものとまったく同じではなく(例:末尾のスラッシュがない)、XPathでプレフィックスが指定されている場合、クエリはnullを返す場合があります。

XMLの名前空間URNが信頼できない場合、構文

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

動作します。

3
ajeh