Как я могу перечислить все пространство имен в XML? - PullRequest
12 голосов
/ 20 апреля 2009

Моё основное требование - получить значение элемента из файла XML, я использовал XMLDoxument.SelectSingleNode. Мой XML-файл содержит некоторое пространство имен в заголовке, поэтому я использовал NameSpaceManager, чтобы добавить префикс пространства имен, и я использовал префикс, чтобы получить этот конкретный элемент. Теперь в моих XML-файлах пространства имен меняются, я не хочу выполнять жесткое кодирование, есть ли способ узнать все пространства имен и добавить его в NameSpaceManager.

Спасибо.

Ответы [ 5 ]

14 голосов
/ 06 ноября 2014

Пространства имен можно найти в любом месте внутри XML-документа. Поэтому, чтобы извлечь все пространства имен и объявить их в XmlNamespaceManager, я сделал следующее:

public static XmlNamespaceManager getAllNamespaces(XmlDocument xDoc)
{
    XmlNamespaceManager result = new XmlNamespaceManager(xDoc.NameTable);

    IDictionary<string, string> localNamespaces = null;
    XPathNavigator xNav = xDoc.CreateNavigator();
    while (xNav.MoveToFollowing(XPathNodeType.Element))
    {
        localNamespaces = xNav.GetNamespacesInScope(XmlNamespaceScope.Local);
        foreach (var localNamespace in localNamespaces)
        {
            string prefix = localNamespace.Key;
            if (string.IsNullOrEmpty(prefix))
                    prefix = "DEFAULT";

            result.AddNamespace(prefix, localNamespace.Value);
        }
    }

    return result;
}

Просто обратите внимание на регистр имен по умолчанию. Я переопределил пространство имен по умолчанию в качестве префикса «DEFAULT», потому что у меня были проблемы при создании SelectSingleNode с помощью вышеупомянутого менеджера пространства имен при запросе пространства имен по умолчанию. Я был моим обходным путем. Надеюсь, это поможет

8 голосов
/ 20 апреля 2009

Спасибо за ваш быстрый ответ ...

Я думаю, что используемая вами версия .Net должна быть самой последней. Я использую .Net Framework 1.1 ... довольно старый :( ..

К тому времени, у меня есть пример кода вроде этого .. для той же цели ...

XmlNodeList _xmlNameSpaceList =  _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]");

            _xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);        

            foreach(XmlNode nsNode in _xmlNameSpaceList)
            {
                _xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value);
            }

Любой комментарий будет оценен, чтобы добавить знания в мою КБ ... Спасибо

2 голосов
/ 07 февраля 2018

Ручита выложил рабочий раствор на XmlDocument. Но я хотел сделать то же самое с XDocument. Вот то же самое с XDocument:

var xml = XDocument.Load(filename);
var xmlNameSpaceList = ((IEnumerable)xml.XPathEvaluate(@"//namespace::*[not(. = ../../namespace::*)]")).Cast<XAttribute>();
var xmlNSmgr = new XmlNamespaceManager(new NameTable());
foreach (var nsNode in xmlNameSpaceList)
{
    xmlNSmgr.AddNamespace(nsNode.Name.LocalName, nsNode.Value);
}

Теперь вы можете использовать XPath с пространствами имен, например, xml.XPathEvaluate("//test:p", xmlNSmgr).

2 голосов
/ 20 апреля 2009

Ваша основная проблема получения пространств имен из XmlDocument может быть решена простым извлечением NameTable XmlDocument и созданием XmlNameSpaceManager из него.

Однако, если вы хотите перечислить пространства имен для какой-либо другой цели, вы должны проверить метод GetNamespacesInScope, предоставляемый классом XmlNamespaceManager, а также классом XPathNavigator.

При использовании XmlDocument вы можете получить из него XmlNamespaceManager с помощью следующего кода:

//Instantiate an XmlDocument object.
XmlDocument xmldoc = new XmlDocument();

//Load XML file into the XmlDocument object. 
xmldoc.Load("C:\\myFile.xml");

//Instantiate an XmlNamespaceManager object. 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable);

// Retrieve the namespaces into a Generic dictionary with string keys.
IDictionary<string, string> dic = nsMgr.GetNamespacesInScope(XmlNamespaceScope.All);

// Iterate through the dictionary.

...

В этой статье Скотт Хансельман представляет способ использования этого метода для вывода списка всех пространств имен в документе с помощью XPathNavigator и моста LINQ.

0 голосов
/ 06 апреля 2011

Если вы ищете быстрый способ избежать проблемы с пространством имен, удалите определения пространства имен из XML через RegEx, прежде чем выполнять XmlDocument.LoadXml (bla). Я делаю это при разборе живых страниц XHTML. Увеличивает время загрузки XmlDoc с 15 секунд до 0,15 секунд и делает так, чтобы мне не нужно было добавлять префиксы к моим xpaths.

...