如何使用 MSXML 查询默认命名空间 [英] How to query default namespace with MSXML

查看:30
本文介绍了如何使用 MSXML 查询默认命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 XML:

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

注意:这不是我正在使用的实际 XML,它只是更漂亮和更短,并说明了问题.

Note: This isn't the actual XML i'm using, it's just prettier and shorter, and demonstrates the problem.

使用 MSXML 我可以查询节点:

Using MSXML i can query for nodes:

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

它工作正常:

条件="'$(key)'=='1111'"

Condition="'$(key)'=='1111'"

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

实际上,我拥有的 XML 包含一个命名空间声明:

But that's not really the XML i have

In reality the XML i have contains a namespace declaration:

xmlns="http://schemas.microsoft.com/developer/msbuild/2003"

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 查询默认命名空间?

How do i query the default namespace using MSXML?

注意:

  • i already know how to query the non-default namespace in xml; you use:

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

  • 我已经知道如何查询 .NET 中的默认命名空间.您使用命名空间管理器,为默认命名空间命名,然后使用该名称进行查询,然后您可以查询非默认命名空间,因为它不再是默认的

  • i already know how to query the default namespace in .NET. You use the namespace manager, give the default namespace a name, then query using that name, then you can query the non-default namespace since it's no longer default

    可以只是从我收到的 XML 字符串中删除令人反感的 xmlns 文本,但我宁愿以正确的方式去做"

    i can just delete the offensive xmlns text from the XML string i receive, but i'd rather "do it the right way"

    如何使用 MSXML 查询 default"unnamed" 命名空间?

    How do i query the "default", or "unnamed" namespace using MSXML?

    注意:实际上我使用的是 SQL Server 的 XML ShowPlan 输出的 XML:

    Note: In reality the XML i am using the SQL Server's XML ShowPlan output:

    <?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> 
    

    您再次可以看到有问题的命名空间声明.删除它有效,但很乏味.

    Again you can see the offending namespace declaration. Deleting it works, but that's tedious.

    我也尝试设置SelectionNamespace:

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

    微软在知识库文章中暗示.

    实际上我并不关心命名空间.我的查询是有道理的,我希望它起作用.所以,这个问题的另一种方法可能是:

    In reality i don't care about namespaces. My query makes sense, and i want it to work. So, Another approach to the question might be:

    我如何查询默认命名空间,无论该命名空间名称是否是(或不是)?

    How can i query the default namespace whether, or not, and no matter what, that namespace name is (or isn't)?

    注意:msxml 是本机代码,从本机 Win32 编译器(即没有 .NET 框架或 CLR)使用它

    Note: msxml is native code, and using it from a native Win32 compiler (i.e. no .NET framework or CLR)

    推荐答案

    在将命名空间添加到 SelectionNamespaces 时,显式地为其命名:

    Explicitly give the namespace a name when you add it to the SelectionNamespaces:

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

    然后查询使用那个命名空间:

    and then query using that namespace:

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

    您可以为该命名空间指定任何您想要的缩写名称(在本例中为 peanut).然后使用缩写作为前缀(在本例中为peanut:PropertyGroup).

    You can give that namespace any abbreviation name you want (peanut in this case). And then use the abbreviation as prefix (peanut:PropertyGroup in this case).

    我会尝试转向 Xml.Linq.

    这是一个示例(带有命名空间).

    Here is a sample (with a namespace).

          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);
        }
    

    这篇关于如何使用 MSXML 查询默认命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆