2015-06-18 1 views
0

У меня есть следующий XML-файл с именем file.xml:Выбор внутреннего текста узлов XML и добавить в список

<?xml version="1.0"?> 
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"> 
    <defaults> 
     <serializer>pof</serializer> 
    </defaults> 
    <caching-scheme-mapping> 
     <cache-mapping> 
      <cache-name>broadcast-data|position</cache-name> 
      <scheme-name>broadcast</scheme-name> 
     </cache-mapping> 
     <cache-mapping> 
      <cache-name>broadcast-data|position-audit</cache-name> 
      <scheme-name>broadcast-remote</scheme-name> 
     </cache-mapping> 
     <cache-mapping> 
      <cache-name>broadcast-data|trade</cache-name> 
      <scheme-name>broadcast-remote</scheme-name> 
     </cache-mapping> 
    </caching-scheme-mapping> 
</cache-config> 

Я пытаюсь получить внутренний текст всех имен кэш-памяти, которые существуют в рамках каждого cache-mapping node и поместить их в список. Для этого у меня есть класс Model.cs.

class Model 
{ 
    private XmlDocument cacheFile = new XmlDocument(); 
    private List<string> cacheNames = new List<string>(); 
    private int nameCount = 0; 


    public Model() 
    { 
     this.loadNames(); 
    } 

    public void loadNames() 
    { 
     try //exception handling 
     { 
      cacheFile.Load("../../resources/file.xml"); 

     } 
     catch (System.IO.FileNotFoundException) 
     { 
      Debug.WriteLine("File not found!"); 
      Environment.Exit(1); 
     } 
     catch (System.ArgumentException) 
     { 
      Debug.WriteLine("Invalid path!"); 
      Environment.Exit(1); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine("Exception thrown!"); 
      Debug.WriteLine(e); 
      Environment.Exit(1); 
     } 

     //get cache names 
     XmlNodeList nodes = cacheFile.SelectNodes("/cache-config/caching-scheme-mapping/cache-mapping"); 

     foreach (XmlNode node in nodes) 
     { 
      string name = node.FirstChild.InnerText; 
      cacheNames.Add(name); 
      nameCount++; 

     } 

    } 
    //accessors 
    public List<string> getCacheNames() 
    { 
     return cacheNames; 
    } 
    public int getNameCount() 
    { 
     return nameCount; 
    } 

} 

Однако каждый раз, когда я создаю объект модели, а затем проверить, если список был загружен, он говорит мне, что список пуст! Кажется, что цикл foreach никогда не запускается, или как будто программа не может найти узлы, которые я указываю. Пожалуйста помоги.

+1

По какой-либо причине вы должны использовать 'XmlDocument' вместо LINQ to XML? Последнее, как правило, гораздо приятнее в использовании ... –

+0

Вы должны пройти через него с помощью отладчика. Я собираюсь опасаться, что ваш список 'nodes' пуст, поскольку вы игнорируете пространство имен ваших элементов. Как поясняет @JonSkeet, «XDocument» было бы намного легче работать с этим. –

+0

@JonSkeet Я новичок в .NET, поэтому я просто следил за некоторой документацией MSDN, которая использовала 'XmlDocument' –

ответ

2

Если вы используете LINQ к XML, это действительно довольно просто:

XNamespace ns = "http://xmlns.oracle.com/coherence/coherence-cache-config";    

var doc = XDocument.Load("../../resources/file.xml"); 

cacheNames = doc.Descendants(ns + "cache-name").Select(e => e.Value).ToList(); 

Вам не нужно держать отдельный подсчет элементов, вы можете получить это из списка:

cacheNames.Count; 

Как и в ином случае, C# использует pascal casing для методов и свойств, поэтому, если вы придерживаетесь этого, ваши методы начинаются с заглавной буквы - например GetCacheNames.

+0

спасибо! это сработало. –

0

Это вызывало недоумение у многих и много раз было задано здесь, в SO. Ваш XML имеет пространство имен по умолчанию здесь:

xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config" 

Потомок элементы наследуют предок пространство имен по умолчанию, если не указано иное (с использованием явного префикса пространства имен или имеющих локальное пространство имен по умолчанию, которые ссылаются на другое пространство имен URI). Использование XmlDocument вы можете использовать XmlNamespaceManager зарегистрировать префикс пространства имен отображение URI, и использовать зарегистрированный префикс должным образом в вашем XPath запроса, например:

var nsMgr = new XmlNamespaceManager(new NameTable()); 
nsMgr.AddNamespace("d", "http://xmlns.oracle.com/coherence/coherence-cache-config"); 
var xpath = "/d:cache-config/d:caching-scheme-mapping/d:cache-mapping"; 
XmlNodeList nodes = cacheFile.SelectNodes(xpath, nsMgr); 

Во всяком случае, если вы только начали это, переход на более новый класс XDocument бы быть лучшим вариантом.