如何查询与MSXML默认命名空间(How to query default namespace wi

2019-09-02 14:03发布

我有一些XML:

<?xml version="1.0" ?>
<Project ToolsVersion="4.0">
    <PropertyGroup Condition="'$(key)'=='1111'">
          <Key>Value</Key>
    </PropertyGroup>
</Project>

注意 :这不是实际的XML我使用,它只是漂亮,更短,并演示了此问题。

使用MSXML我可以查询节点:

IXMLDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition");

并能正常工作:

条件= “ '$(密钥)' == '1111'”

但是,这并不是真正的XML,我有

在现实中,XML,我有包含命名空间声明:

的xmlns = “http://schemas.microsoft.com/developer/msbuild/2003”

在进行实际的XML文档:

<?xml version="1.0" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup Condition="'$(key)'=='1111'">
          <Key>Value</Key>
    </PropertyGroup>
</Project>

现在我的查询:

IDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition");

没有返回匹配的节点。

我如何使用MSXML查询默认的命名空间?

注意

  • 我已经知道如何查询XML中的非默认的命名空间 ; 你用:

      doc.setProperty("SelectionNamespaces", "xmlns="http://schemas.microsoft.com/developer/msbuild/2003"); 
  • 我已经知道如何查询在.NET中的默认命名空间 。 您可以使用命名空间管理,给默认的命名空间的名称,然后查询中使用该名称,然后你就可以查询非默认的命名空间,因为它不再是默认

  • 我只是删除了进攻xmlns从XML字符串我收到的文字,但我宁愿“做正确的方式”

如何查询“默认”“无名”命名空间使用MSXML?


:在现实中我使用的是SQL Server的XML 显示计划输出的XML:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
   <ShowPlanXML Version="1.1" Build="10.50.1600.1" 
                   xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
      <BatchSequence>
           <Batch>
           ...
           </Batch>
      </BatchSequence>
   </ShowPlanXML> 

同样,你可以看到有问题的命名空间声明。 删除它的工作原理,但这是乏味的。

还有什么你试过吗?

我也尝试设置SelectionNamespace:

doc.setProperty('SelectionNamespaces', 
      'xmlns="http://schemas.microsoft.com/developer/msbuild/2003"');

作为微软暗示在知识库文章中 。

我如何得到默认的命名空间?

在现实中,我不关心的命名空间。 我的查询是有道理的,我想它的工作。 所以,这个问题的另一种方法可能是:

我怎样才能查询默认的命名空间是否与否,也不管该命名空间的名字是什么,(或者不是)?

:MSXML是本地代码,并使用它从一个本机Win32编译器(即没有.NET Framework或CLR)

Answer 1:

明确给出的命名空间的名字,当你将它添加到SelectionNamespaces

doc.setProperty("SelectionNamespaces",
      "xmlns:peanut='http://schemas.microsoft.com/developer/msbuild/2003'");

然后查询中使用该命名空间:

IDOMNode node = doc.selectSingleNode("//peanut:PropertyGroup/@Condition");

你可以给该命名空间你想要(任何缩写名称peanut在这种情况下)。 然后使用缩写为前缀( peanut:PropertyGroup在这种情况下)。

此前的建议

我会尝试移动到Xml.Linq

下面是一个示例(与命名空间)。

      try
    {

        XDocument xDoc1 = XDocument.Parse("<?xml version=\"1.0\" ?><Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"><PropertyGroup Condition=\"'$(key)'=='1111'\"><Key>Value</Key></PropertyGroup></Project>");
        XNamespace ns1 = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");

        var list1 = from list in xDoc1.Descendants(ns1 + "Project")
                    from item in list.Elements(ns1 + "PropertyGroup")
                    /* where item.Element(ns + "HintPath") != null */
                    where item.Attribute("Condition") != null
                    select new
                    {
                        MyCondition = item.Attribute("Condition") == null ? "Not Here!" : item.Attribute("Condition").Value,
                        MyFake = item.Attribute("DoesNotExistTest") == null ? "Not Here Sucker!" : item.Attribute("DoesNotExistTest").Value
                    };


        foreach (var v in list1)
        {
            Console.WriteLine(v.ToString());
        }


        XDocument xDoc2 = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>   <ShowPlanXML Version=\"1.1\" Build=\"10.50.1600.1\"                    xmlns=\"http://schemas.microsoft.com/sqlserver/2004/07/showplan\">      <BatchSequence>            <Batch>Something I Threw In Here</Batch>      </BatchSequence>    </ShowPlanXML> ");
        XNamespace ns2 = XNamespace.Get("http://schemas.microsoft.com/sqlserver/2004/07/showplan");

        var list2 = from list in xDoc2.Descendants(ns2 + "ShowPlanXML")
                    from item in list.Elements(ns2 + "BatchSequence")
                    /*                             where item.Attribute("Condition") != null */
                    where item.Element(ns2 + "Batch") != null 
                    select new
                    {
                        BatchValue = (item.Element(ns2 + "Batch") == null) ? string.Empty : item.Element(ns2 + "Batch").Value
                    };


        foreach (var v in list2)
        {
            Console.WriteLine(v.ToString());
        }



    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }


文章来源: How to query default namespace with MSXML