web-dev-qa-db-fra.com

Vous ne pouvez pas obtenir xmldocument.selectNodes de récupérer l'un de mes nœuds?

J'essaie d'analyser un document XML. Le document en question est un fichier AppXManifest.

Un exemple de document ressemble à ceci:

<?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>

J'essaie de l'analyser comme si:

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");

Cependant, après avoir exécuté cela, nodes ne contiendra jamais rien. Le document XML est chargé et tel cependant. Utilisation SelectNodes("//*") Retourne chaque noeud comme prévu. Quel est mon problème ici?

J'ai aussi essayé de nombreuses variations sur cette requête XPath telle que

  • /Package/Applications/Application
  • Applications/Application
  • Applications/*

Rien ne semble récupérer le nœud unique cependant. Idéalement, je voudrais que les nœuds contiennent tous les nœuds Application

17
Earlz

Vous devez utiliser un espace de noms XML spécifiquement pour les sélectionner. envisager

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

dans votre cas, ce code peut aussi bien fonctionner:

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

Vous devez spécifier des préfixes pour les espaces de noms dans NAMESPAcemanager et XPaths. Notez que les préfixes n'ont pas besoin de faire correspondre quoi que ce soit, sauf entre votre XPath et votre responsable de l'espace de noms *.

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);

Et comme indiqué par d'autres réponses, XPath accepte tout espace de noms est une autre option.

*) C'est à dire. Dans votre exemple particulier, il existe 2 espaces de noms "par défaut" (notez que le préfixe par défaut n'est pas le même que l'espace de noms vide) et "Construire". Ainsi, lorsque vous définissez votre gestionnaire d'espaces de noms, vous devez spécifier un préfixe pour chacun de l'espace de noms (si vous devez cibler les nœuds dans les deux), mais les préfixes peuvent être des chaînes arbitraires (valables pour les préfixes mais non vides). C'est à dire. Utilisez "A" pour "espace de noms" par défaut "et" bar "pour l'espace de noms qui mappé sur" Construire "dans le XML.

9
Alexei Levenkov

Vous pourriez avoir besoin de lire ceci

Voici votre code:

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

Pas dans ce cas particulier, mais en général, si l'urne d'espace de noms dans le XML réel n'est pas exactement la même que celle utilisée pour ajouter un espace de noms à un gestionnaire de cartes de noms (exemple: une barre oblique de fuite) et un préfixe est spécifié dans XPATH , la requête peut retourner null.

Si l'urne d'espace de noms dans le XML n'est pas fiable, Syntaxe

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

marchera.

3
ajeh