1

我有以下名为 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>

我正在尝试获取每个缓存映射节点下存在的所有缓存名称的内部文本,并将它们全部放在一个列表中。我有这个 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 循环从未真正运行过,或者好像程序找不到我指定的节点。请帮忙。

4

2 回答 2

3

如果你使用 LINQ to 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 大小写,因此如果您坚持这一点,您的方法将以大写字母开头 - 例如GetCacheNames.

于 2015-06-18T14:28:09.747 回答
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将是一个更好的选择。

于 2015-06-18T14:32:52.900 回答