Использование Xpath с пространством имен по умолчанию в C#

JSON.parse () преобразует любую строку JSON, переданную в функцию, в объект JSON.

Для лучшего понимания нажмите F12, чтобы открыть элемент Inspect Element своего браузера и перейти к консоли, чтобы написать следующие команды: -

var response = '{"result":true,"count":1}'; //sample json object(string form)
JSON.parse(response); //converts passed string to JSON Object.

Теперь запустите команду: -

console.log(JSON.parse(response));

вы получите вывод как Object {result: true, count: 1}.

Чтобы использовать этот объект, вы можете назначить его переменной, скажем, obj: -

var obj = JSON.parse(response);

Теперь, используя оператор obj и dot (.), Вы можете получить доступ к свойствам объекта JSON.

Попробуйте запустить команду

console.log(obj.result);
61
задан macleojw 25 February 2009 в 12:34
поделиться

6 ответов

Сначала - Вам не нужен навигатор; SelectNodes / SelectSingleNode должен быть достаточным.

Вам, возможно, однако, понадобится менеджер пространства имен - например:

XmlElement el = ...; //TODO
XmlNamespaceManager nsmgr = new XmlNamespaceManager(
    el.OwnerDocument.NameTable);
nsmgr.AddNamespace("x", el.OwnerDocument.DocumentElement.NamespaceURI);
var nodes = el.SelectNodes(@"/x:outerelement/x:innerelement", nsmgr);
80
ответ дан Marc Gravell 7 November 2019 в 13:27
поделиться

В этом случае это - вероятно, разрешение пространства имен, которое является причиной проблемы, но также возможно, что Ваше выражение XPath не корректно сам по себе. Можно хотеть оценить его сначала.

Вот код с помощью XPathNavigator.

//xNav is the created XPathNavigator.
XmlNamespaceManager mgr = New XmlNamespaceManager(xNav.NameTable);
mgr.AddNamespace("prefix", "http://tempuri.org/");

XPathNodeIterator result = xNav.Select("/prefix:outerelement/prefix:innerelement", mgr);
0
ответ дан Cerebrus 7 November 2019 в 13:27
поделиться

В случае, если пространства имен отличаются для outerelement и innerelement

XmlNamespaceManager manager = new XmlNamespaceManager(myXmlDocument.NameTable);
                            manager.AddNamespace("o", "namespaceforOuterElement");
                            manager.AddNamespace("i", "namespaceforInnerElement");
string xpath = @"/o:outerelement/i:innerelement"
// For single node value selection
XPathExpression xPathExpression = navigator.Compile(xpath );
string reportID = myXmlDocument.SelectSingleNode(xPathExpression.Expression, manager).InnerText;

// For multiple node selection
XmlNodeList myNodeList= myXmlDocument.SelectNodes(xpath, manager);
5
ответ дан Rashmi Pandit 7 November 2019 в 13:27
поделиться

Вы можете попробовать инструмент XPath Visualizer, который поможет вам в этом.

XPathVisualizer бесплатен и прост в использовании.

alt text

ВАЖНО: Если вы используете Windows 7/8 и не видите пункты меню «Файл», «Правка» и «Справка», нажмите клавишу ALT.

48
ответ дан 24 November 2019 в 16:59
поделиться

В моем случае добавление префикса не было практично. Слишком большая часть XML или XPath была определена во время выполнения. В конце концов я расширил METHDS на XMLNode. Это не было оптимизировано для производительности, и он, вероятно, не справится с каждым случаем, но он до сих пор работает для меня.

    public static class XmlExtenders
{

    public static XmlNode SelectFirstNode(this XmlNode node, string xPath)
    {
        const string prefix = "pfx";
        XmlNamespaceManager nsmgr = GetNsmgr(node, prefix);
        string prefixedPath = GetPrefixedPath(xPath, prefix);
        return node.SelectSingleNode(prefixedPath, nsmgr);
    }

    public static XmlNodeList SelectAllNodes(this XmlNode node, string xPath)
    {
        const string prefix = "pfx";
        XmlNamespaceManager nsmgr = GetNsmgr(node, prefix);
        string prefixedPath = GetPrefixedPath(xPath, prefix);
        return node.SelectNodes(prefixedPath, nsmgr);
    }

    public static XmlNamespaceManager GetNsmgr(XmlNode node, string prefix)
    {
        string namespaceUri;
        XmlNameTable nameTable;
        if (node is XmlDocument)
        {
            nameTable = ((XmlDocument) node).NameTable;
            namespaceUri = ((XmlDocument) node).DocumentElement.NamespaceURI;
        }
        else
        {
            nameTable = node.OwnerDocument.NameTable;
            namespaceUri = node.NamespaceURI;
        }
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(nameTable);
        nsmgr.AddNamespace(prefix, namespaceUri);
        return nsmgr;
    }

    public static string GetPrefixedPath(string xPath, string prefix)
    {
        char[] validLeadCharacters = "@/".ToCharArray();
        char[] quoteChars = "\'\"".ToCharArray();

        List<string> pathParts = xPath.Split("/".ToCharArray()).ToList();
        string result = string.Join("/",
                                    pathParts.Select(
                                        x =>
                                        (string.IsNullOrEmpty(x) ||
                                         x.IndexOfAny(validLeadCharacters) == 0 ||
                                         (x.IndexOf(':') > 0 &&
                                          (x.IndexOfAny(quoteChars) < 0 || x.IndexOfAny(quoteChars) > x.IndexOf(':'))))
                                            ? x
                                            : prefix + ":" + x).ToArray());
        return result;
    }
}

Тогда в вашем коде просто используйте что-то вроде

        XmlDocument document = new XmlDocument();
        document.Load(pathToFile);
        XmlNode node = document.SelectFirstNode("/rootTag/subTag");

Надеюсь, это поможет

3
ответ дан 24 November 2019 в 16:59
поделиться

При использовании XPath в .NET (через навигатор или SelectNodes / SelectSingleNode) на XML с пространствами имен вам необходимо:

  • предоставить свой собственный XmlNamespaceManager

  • и явным префиксом для всех элементы в выражении XPath, которые находятся в пространстве имен.

Последнее (перефразировано из источника MS, ссылка на который приведена ниже): потому что XPath 1.0 игнорирует спецификации пространства имен по умолчанию (xmlns = "some_namespace"). Поэтому, когда вы используете имя элемента без префикса, оно предполагает пустое пространство имен.

Вот почему реализация XPath в .NET игнорирует пространство имен с префиксом String.Empty в XmlNamespaceManager и всегда использует пустое пространство имен.

См. XmlNamespaceManager и UndefinedXsltContext не обрабатывают пространство имен по умолчанию для получения дополнительной информации.

Я нахожу эту «возможность» очень неудобной, потому что вы не можете сделать старый XPath зависимым от пространства имен, просто добавив объявление пространства имен по умолчанию, но именно так это работает.

20
ответ дан 24 November 2019 в 16:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: