Выбор атрибутов пространства имен XML с псевдонимом пространства имен вместо URI в XElement - PullRequest
3 голосов
/ 18 февраля 2012

Я пытаюсь запросить некоторую информацию из 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
    };

Это работает нормально, но я бы хотел найти атрибуты, используя пространство имен псевдонимы , а не URI пространства имен (только потому, что), илипо крайней мере, иметь возможность искать URI, используя псевдоним.Чтобы попробовать последнюю идею, я в конце концов понял, что могу сделать это:

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

Но я получаю XmlException: Символ ':', шестнадцатеричное значение 0x3A, нельзя включить в имя.

Итак, я попытался:

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

И тогда это работает, но кажется, что может быть или должен быть более простой способ, или, скорее, синтаксис {namespace}attribute кажется мне глупым,как что-то, что может быть абстрагировано в рамках.

  • Итак, есть ли какие-либо ярлыки или более простые способы поиска атрибутов пространства имен?

Буду признателен за любые отзывы.Спасибо!

1 Ответ

6 голосов
/ 18 февраля 2012

с использованием 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 );
}
...