Вопрос

Я пробую очень простой XPath на этот xml- файл (то же, что и ниже), и он ничего не находит.Я пробую и то, и другое.СЕТЬ и этот веб-сайт, и XPaths , такие как //PropertyGroup, /PropertyGroup и //MSBuildCommunityTasksPath у меня просто не работают (они компилируются, но возвращают нулевые результаты).

Исходный XML:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ -->
    <PropertyGroup>
        <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug</MSBuildCommunityTasksPath>
    </PropertyGroup>
    <Import
        Project="$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\MSBuild.Community.Tasks.Targets" />
    <Target Name="DoFxCop">
        <FxCop TargetAssemblies="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll"
            RuleLibraries="@(FxCopRuleAssemblies)" 
            AnalysisReportFileName="Test.html"
            DependencyDirectories="$(MSBuildCommunityTasksPath)" 
            FailOnError="True"
            ApplyOutXsl="True"
            OutputXslFileName="C:\Program Files\Microsoft FxCop 1.32\Xml\FxCopReport.xsl" />
    </Target>
</Project>
Это было полезно?

Решение

Вы можете добавлять пространства имен в свой код и все такое, но вы можете эффективно использовать подстановочные знаки для пространства имен.Попробуйте использовать следующую идиому XPath.

//*[local-name()='PropertyGroup']
//*[local-name()='MSBuildCommunityTasksPath']

name() обычно работает так же хорошо, как и в:

//*[name()='PropertyGroup']
//*[name()='MSBuildCommunityTasksPath']

Редактировать: Пространства имен - это здорово и я не утверждаю, что они не важны, но их подстановочные знаки пригодятся при создании прототипа кода, одноразовых инструментов для настольных компьютеров, экспериментировании с XSLT и так далее.Сбалансируйте свою потребность в удобстве с приемлемым риском для выполнения поставленной задачи.К вашему сведению, при необходимости вы также можете удалить или переназначить пространства имен.

Другие советы

Теги в документе попадают в пространство имен "по умолчанию", созданное атрибутом xmlns без префикса.К сожалению, один только XPath не может запрашивать элементы в пространстве имен по умолчанию.На самом деле я не уверен в семантических деталях, но вы должны явно присоединить префикс к этому пространству имен, используя любой инструмент, на котором размещен XPath.

Возможно, есть более короткий способ сделать это в .NET, но единственный способ, который я видел, - это через NamespaceManager.После явного добавления пространства имен вы можете запросить с помощью диспетчера пространств имен, как если бы все теги в элементе пространства имен имели этот префикс (я выбрал 'msbuild').:

using System;
using System.Xml;

public class XPathNamespace {
    public static void Main(string[] args) {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(
    @"<?xml version=""1.0"" encoding=""utf-8""?>
<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
    <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ -->

    <PropertyGroup>
        <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug</MSBuildCommunityTasksPath>
    </PropertyGroup>

    <Import Project=""$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\MSBuild.Community.Tasks.Targets""/>

    <Target Name=""DoFxCop"">

        <FxCop 
            TargetAssemblies=""$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll""
            RuleLibraries=""@(FxCopRuleAssemblies)"" 
            AnalysisReportFileName=""Test.html""
            DependencyDirectories=""$(MSBuildCommunityTasksPath)""
            FailOnError=""True""
            ApplyOutXsl=""True""
            OutputXslFileName=""C:\Program Files\Microsoft FxCop 1.32\Xml\FxCopReport.xsl""
        />
    </Target>

</Project>");

        XmlNamespaceManager namespaceManager = new
    XmlNamespaceManager(xmlDocument.NameTable);
        namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003");
        foreach (XmlNode n in xmlDocument.SelectNodes("//msbuild:MSBuildCommunityTasksPath", namespaceManager)) {
            Console.WriteLine(n.InnerText);
        }
    }
}

Ваша проблема связана с пространством имен (xmlns="http://schemas.microsoft.com/developer/msbuild/2003").Вы получаете нулевые узлы, потому что вы не указываете их в пространстве имен.Если вы удалите атрибут xmlns, ваш XPath "//PropertyGroup" будет работать.То, как вы выполняете запрос с помощью пространства имен, обычно включает в себя присвоение идентификатора xmlns по умолчанию идентификатору (поскольку он не указан в атрибуте) и выбор типа "//myXMLNStoken:PropertyGroup".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top