Вы уже ответили на вопрос, но стоит понять, почему это так.
Пространство имен, в котором находится элемент, не может быть определено исключительно префиксом пространства имен. Чтобы найти, в каком пространстве имен находится элемент с именем t:foo
, вы должны искать по оси ancestor-or-self, пока не найдете ближайший узел, который определяет пространство имен для t:
. Например:
<t:one xmlns:t="ns-one">
<t:one>
<t:two xmlns:t="ns-two">
<t:two/>
</t:two>
</t:one>
</t:one>
В этом документе каждый элемент с именем one
находится в пространстве имен ns-one
, а каждый элемент с именем two
находится в пространстве имен ns-two
. Вы можете сказать, что самый глубокий элемент в этом документе находится в ns-two
не потому, что t:
по сути означает ns-two
, а потому, что если вы ищите ось предка или самого себя, первый элемент, который вы нажали с xmlns:t
атрибут на нем - его родитель - сообщает вам пространство имен.
Учитывая, с какими узлами должно совпадать выражение XPath //t:*
? Невозможно сказать, потому что то, что пространство имен t:
сопоставлено с изменениями по всему документу.
Кроме того, префиксы пространства имен являются временными, но пространства имен являются постоянными. Если вы знаете, что one
находится в ns-one
, вам действительно все равно, является ли его префикс t:
или x:
или он вообще не имеет префикса и имеет только атрибут xmlns
.
Когда вы запрашиваете XML-документ с помощью XPath, вам нужен способ указать, в каком пространстве имен находится данный элемент. И это то, что SelectionNamespaces
в DOMDocument, или менеджер пространства имен в C #, или что-то для: они сообщают вам, какие пространства имен представляют префиксы в ваших запросах XPath. Поэтому, если я установил префикс a:
в ns-one
, XPath //a:one
найдет мне все элементы с именем one
в пространстве имен ns-one
, независимо от того, какой фактический префикс они используют в документ, который я ищу -
Это немного нелогично, когда вы впервые изучаете его, но на самом деле, это единственный способ, который вообще имеет какой-либо смысл.