选择命名空间的XML节点的命名空间别名,而不是URI属性上的XElement空间、别名、节点、而不是

2023-09-06 18:18:39 作者:luck one

我想查询从一个重命名空间的XML文档中的一些信息和时遇到一些麻烦发现,也命名空间的属性。

I'm trying to query out some information from a heavily namespaced XML document and am having some trouble finding attributes that are also namespaced.

中的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>

我的目标是创建具有国code和国家名称的对象列表。以下是我的作品现在:

My goal is to create a list of objects that have a country code and a country name. Here's what works for me now:

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

这工作得很好,但我想找到使用命名空间属性的别名,而不是名称空间URI(只是因为),或至少能够使用别名来查找URI。要尝试后者的想法,我终于想通了,我能做到这一点:

This works fine, but I'd like to find the attributes using the namespace aliases, not the namespace URI (just because), or at least be able to lookup the URI using the alias. To try the latter idea, I eventually figured out I could do this:

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

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

But I get an XmlException: The ':' character, hexadecimal value 0x3A, cannot be included in a name.

于是我想:

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

然后它的作品,但似乎只是有可能或应该有一个更简单的方法,或者说, {空间}属性语法似乎是愚蠢的,我的,喜欢的东西在该框架可能被抽象化了。

And then it works, but just seems like there could or should be an easier way, or rather, the {namespace}attribute syntax seems silly to me, like something that might be abstracted away in the framework.

因此,与这一切,还有什么捷径或者更简单的方法来查找命名空间的属性?

我倒是AP preciate任何反馈。谢谢!

I'd appreciate any feedback. Thanks!

推荐答案

使用LINQ to XML

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