c# - 在 XElement 上选择具有命名空间别名而不是 URI 的命名空间 XML 节点属性

标签 c# .net xml xpath xml-namespaces

我正在尝试从大量命名空间的 XML 文档中查询一些信息,但在查找同样命名空间的属性时遇到了一些问题。

XML 看起来像:

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:skos="http://www.w3.org/2004/02/skos/core#"
    xmlns:geo="http://www.geonames.org/ontology#"
    xmlns:dc="http://purl.org/dc/terms/"
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    xmlns:void="http://rdfs.org/ns/void#">

    <geo:Country rdf:about="http://ontologi.es/place/AD" skos:notation="AD" rdfs:label="Andorra" />
    <geo:Country rdf:about="http://ontologi.es/place/AE" skos:notation="AE" rdfs:label="United Arab Emirates" />
    <geo:Country rdf:about="http://ontologi.es/place/AF" skos:notation="AF" rdfs:label="Afghanistan" />
    <geo:Country rdf:about="http://ontologi.es/place/AG" skos:notation="AG" rdfs:label="Antigua &amp; Barbuda" />
    <geo:Country rdf:about="http://ontologi.es/place/AI" skos:notation="AI" rdfs:label="Anguilla" />
    <geo:Country rdf:about="http://ontologi.es/place/AL" skos:notation="AL" rdfs:label="Albania" /> 
    ...

</rdf:RDF>

我的目标是创建一个包含国家代码和国家名称的对象列表。以下是现在对我有用的:

XmlReader reader = XmlReader.Create(@"path/to/xml.xml");
XDocument root = XDocument.Load(reader);
XmlNameTable nameTable = reader.NameTable;

XmlNamespaceManager nsManager = new XmlNamespaceManager(nameTable);
nsManager.AddNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
nsManager.AddNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
nsManager.AddNamespace("skos", "http://www.w3.org/2004/02/skos/core#");
nsManager.AddNamespace("geo", "http://www.geonames.org/ontology#");

var geoCountries = 
    from country in root.XPathSelectElements("./rdf:RDF/geo:Country", nsManager)
    select new {
        CountryCode = country.Attributes("{http://www.w3.org/2004/02/skos/core#}notation").First().Value,
        CountryName = country.Attributes("{http://www.w3.org/2000/01/rdf-schema#}label").First().Value
    };

这很好用,但我想使用命名空间 aliases 查找属性,而不是命名空间 URI(只是因为),或者至少能够使用别名查找 URI。为了尝试后一种想法,我最终发现我可以这样做:

country.Attributes(nsManager.LookupNamespace("skos") + "notation").First().Value

但我得到一个 XmlException:':' 字符,十六进制值 0x3A,不能包含在名称中。

然后我尝试了:

country.Attributes("{" + nsManager.LookupNamespace("skos") + "}notation").First().Value

然后它起作用了,但似乎可能或应该有一种更简单的方法,或者更确切地说,{namespace}attribute 语法对我来说似乎很愚蠢,就像一些可能被抽象掉的东西框架。

  • 综上所述,是否有任何快捷方式或更简单的方法来查找命名空间属性?

如果有任何反馈,我将不胜感激。谢谢!

最佳答案

使用 Linq to xml

XNamespace skos = XNamespace.Get("http://www.w3.org/2004/02/skos/core#");
XNamespace geo = XNamespace.Get("http://www.geonames.org/ontology#");
XNamespace rdfs = XNamespace.Get("http://www.w3.org/2000/01/rdf-schema#");

XDocument rdf = XDocument.Load(new StringReader(xmlstr));
foreach(var country in rdf.Descendants(geo + "Country"))
{
    Console.WriteLine(
        country.Attribute(skos + "notation").Value + " "  + 
        country.Attribute(rdfs + "label").Value );
}

关于c# - 在 XElement 上选择具有命名空间别名而不是 URI 的命名空间 XML 节点属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9335756/

相关文章:

c# - Asp MVC 4 创建类似于 Html.BeginForm 的自定义 html 帮助器方法

c# - 从 Dispose() 触发事件是否可以?

xml - 从 child 开始计算祖 parent 内的父节点。 XSL

c# - 将 Linq 查询结果转换为字典

c# - 在结构上获取 Span<byte> 而不复制结构

c# - asp.net core 在上一个操作完成之前在此上下文中开始第二个操作

.net - List (of T) 和 Collection(of T) 有什么区别?

c# - 多个 C# 应用程序可以使用一个 App.Config 文件吗?

android - XML 代码错误?

java - 无法在 Java 中检索 xml 信息