Powershell: XPath не может выбрать, если у элемента есть тег xmlns?

У меня очень простой xml, как показано ниже:

<?xml version="1.0" encoding="utf-8"?>
<First>
  <Second>
    <Folder>today</Folder>
    <FileCount>10</FileCount>
  </Second>
  <Second>
    <Folder>tomorrow</Folder>
    <FileCount>90</FileCount>
  </Second>
  <Second>
    <Folder>yesterday</Folder>
    <FileCount>22</FileCount>
  </Second>
</First>

Затем у меня есть сценарий PowerShell для выбора элемента «Папка»:

[xml]$xml=Get-Content "D:\m.xml"
$xml.SelectNodes("//Folder")

Он выводит:

#text                                                                                                                                                                            
-----                                                                                                                                                                            
today                                                                                                                                                                            
tomorrow                                                                                                                                                                         
yesterday 

Без проблем. Но если я изменю xml-файл, чтобы добавить "xmlns =" ​​http://schemas.microsoft.com/developer/msbuild/2003 "в" Первый ", как показано ниже:

<?xml version="1.0" encoding="utf-8"?>
<First xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Second>
    <Folder>today</Folder>
    <FileCount>10</FileCount>
  </Second>
  <Second>
    <Folder>tomorrow</Folder>
    <FileCount>90</FileCount>
  </Second>
  <Second>
    <Folder>yesterday</Folder>
    <FileCount>22</FileCount>
  </Second>
</First>

Затем мой сценарий PowerShell ничего не выводит. Почему? Как изменить мой сценарий PowerShell для поддержки этого XML?

Большое спасибо.


person vik santata    schedule 24.06.2015    source источник


Ответы (1)


Вы добавили пространство имен по умолчанию. В отличие от пространства имен с префиксом, дочерние элементы наследуют пространство имен по умолчанию предка неявно, если не указано иное (с использованием явного префикса или локального пространства имен по умолчанию, которое указывает на другой URI).

Чтобы выбрать элемент в пространстве имен, вам необходимо определить префикс, указывающий на URI пространства имен, и правильно использовать этот префикс в своем XPath, например:

$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("d", $xml.DocumentElement.NamespaceURI)
$xml.SelectNodes("//d:Folder", $ns)
person har07    schedule 24.06.2015
comment
Спасибо, но seem (1) Создать ns для добавления d (2) Использование d ----- для меня немного избыточно. Почему мне нужно беспокоиться о том, чтобы выбрать // d: Folder, в то время как убедитесь, что $ ns содержит d? Я не нахожу здесь нужного. Кроме того, случайным образом выбирается имя пространства имен по умолчанию, я не вижу смысла в его существовании. Есть ли какие-то более сложные сценарии, которые нужны, чтобы увидеть разницу? Не могли бы вы привести пример? - person vik santata; 24.06.2015
comment
Действительно, префикс d выбирается случайным образом, независимо от того, на какой URI он указывает и какую информацию несет $ns. Тем не менее, вам нужны оба шага (1) и (2) - person har07; 24.06.2015
comment
Чтобы избежать путаницы, случайным образом выбирается не пространство имен по умолчанию, а случайный префикс, который будет использоваться в XPath. Грубо говоря, префикс может быть любым, если он указывает на URI пространства имен по умолчанию. - person har07; 24.06.2015
comment
Спасибо, но я мог бы подумать, если я являюсь разработчиком стандарта XML, я бы рассматривал пространство имен по умолчанию как, тогда использование пустого префикса в порядке. Конечно мое предположение неверно, но почему не может быть так? Я имею в виду, есть ли какие-либо сложные ситуации, когда нам всегда нужна случайно выбранная строка для представления пространства имен по умолчанию, иначе у нас будут логические конфликты? - person vik santata; 24.06.2015
comment
Такое поведение синтаксического анализатора XML на разных языках - может быть, не на всех, но о многих из них, которые я знаю - обусловлено спецификацией XPath - я где-то это читал, может быть, ошибаюсь; исправления приветствуются-. В XPath все элементы без префикса привязаны к пустому пространству имен, тогда как в XML элементы без пространства имен могут находиться в пространстве имен по умолчанию. Во всяком случае, боюсь, я не знаю, почему XPath так спроектирован именно так. - person har07; 24.06.2015
comment
@viksantata обнаружила формальную спецификацию XPath о имени элемента без префикса в XPath, рассматриваемом в пространстве имен null: stackoverflow.com/a/ 22349809/2998271 - person har07; 27.06.2015
comment
Поскольку этот ответ решает проблему, пожалуйста, подумайте о том, чтобы принять это как ответ: meta.stackexchange.com/questions/5234/ - person har07; 27.06.2015