2013-05-10 2 views
11

У меня есть некоторые XML:Как запросить пространство имен по умолчанию с MSXML

<?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"); 

И это прекрасно работает:

Condition = " '$ (ключ)' == '1111'"

Но это на самом деле не XML, который имеет

В действительности XML i содержит объявление пространства имен:

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 to query the non-default namespace in xml; Вы используете:

    doc.setProperty("SelectionNamespaces", 
         "xmlns="http://schemas.microsoft.com/developer/msbuild/2003"); 
    
  • я уже знаю how to query the default namespace in .NET. Вы можете использовать менеджер пространства имен, дать пространство имен по умолчанию имя, то запрос с использованием этого имени, то вы можете запросить пространство имен не по умолчанию, так как он никогда больше не по умолчанию

  • я может просто удалить оскорбительный xmlns текст из XML строку я получаю, но я предпочел бы «сделать это правильный путь»

Как я запросить «по умолчанию» или «безымянный» пространства имен с помощью MSXML?


Примечание: В действительности XML я использую XML ShowPlan в SQL Server в вывод:

<?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"'); 

в Microsoft hints at in a KB article.

Как сделать получить пространство имен по умолчанию?

В действительности я не уход об пространствах имен. Мой запрос имеет смысл, и я хочу, чтобы он работал. Таким образом, другой подход к вопросу может быть следующим:

Как я могу запросить пространство имен по умолчанию, независимо от того, какое имя пространства имен (или нет)?

Примечание: MSXML является родного кода, и использовать его из нативного Win32 компилятора (т.е. нет рамки .NET или CLR)

+0

Я сделал еще одно обновление. Это ударило меня во время поездки домой из кинотеатра. – granadaCoder

+0

@granadaCoder Вы отвечали на StackOverflow во время просмотра фильма !? –

+0

На диске домой я дал несколько моих «циклов» процессора для этой вещи ..... мое радио только что умерло на мне. – granadaCoder

ответ

14

Явных дать пространство имен, имя при добавлении его к 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); 
    } 
+0

Извините, 'IXMLDOMNode', а не' IDOMNode'. Это из *** родной *** msxml COM-библиотеки объектов. И это от родного не (а не .NET) –

+0

Ок. Проверьте мое обновление для подсказки. Я предполагаю, но цифра лучше, чем оставить справедливый ответ .Net. – granadaCoder

+0

Я забыл дать вам ответ; это сработало. Это ужасно ужасно, что вы должны назвать пространство имен по умолчанию, прежде чем сможете его использовать. Но, по крайней мере, это приемлемое решение! –

Смежные вопросы