Как я могу перечислить все пространство имен в XML?
Мое основное требование - получить значение элемента из файла XML, я использовал XMLDoxument.SelectSingleNode. Мой XML файл содержит некоторое пространство имен в заголовке, поэтому я использовал NameSpaceManager для добавления префикса пространства имен и использовал префикс для получения этого конкретного элемента. Теперь в моих XML файлах пространства имен меняются, я не хочу делать какое-либо жесткое кодирование, есть ли способ узнать все пространства имен, и я могу добавить его в NameSpaceManager.
Спасибо.
Ответы
Ответ 1
Пространства имен можно найти где угодно внутри документа 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;
}
Просто обратите внимание на случай пространства имен по умолчанию. Я переопределил пространство имен по умолчанию как префикс "ПО УМОЛЧАНИЮ", потому что у меня возникли проблемы при создании SelectSingleNode с использованием вышеприведенного возвращаемого диспетчера пространства имен при запросе пространства имен по умолчанию. Я был моим помощником.
Надеюсь, что это поможет
Ответ 2
Спасибо за ваш быстрый ответ...
Я думаю, что версия .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);
}
Любой комментарий будет оценен, чтобы добавить знания в мой KB...
Благодаря
Ответ 3
Ваша основная проблема получения пространств имен из 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 моста.
Ответ 4
Ruchita опубликовала рабочее решение для 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)
.
Ответ 5
Если вы ищете быстрый способ избежать проблемы с пространством имен, разделите определения пространства имен из Xml через RegEx, прежде чем вы выполните XmlDocument.LoadXml(bla). Я делаю это при анализе живых страниц XHTML. Занимает время загрузки XmlDoc с 15 секунд до 0,15 секунды и делает это так, что мне не нужно префикс my xpaths.