Подтвердить что ты не робот

XML-элемент имеет пространство имен, мой XPATH не работает

Мне был предоставлен следующий XML:

<root>
  <items>
    <item>
      <title>Item</title>
      <details>
        <data xmlns="http://some_url">
          <length>10</length>
          <weight>1.2</weight>
        </data>
      </details>
    </item>
  </items>
</root>

После XPath не работает, ничего не печатается, поскольку элемент "data" не существует:

/root/items/item/details/data

Но когда я удаляю атрибут пространства имен "xmlns" элемента "data" , его содержимое печатается. Как должно выглядеть выражение xpath, не удаляя атрибут пространства имен "xmlns" элемента "data" ?

Я использую SAXON и XSL 1.0.

4b9b3361

Ответ 1

Это один из самых часто задаваемых вопросов в XPath/XSLT:

XPath интерпретирует неподдерживаемое имя элемента как принадлежащее к "без пространства имен", и поэтому элементы с неподписанными именами, принадлежащими к пространству имен по умолчанию (непустое), не выбраны, когда только их неподписанное имя указано как node - тест в выражении XPath.

Решение::

  • Создайте привязку пространства имен, где префикс (скажем "x") связан с пространством имен по умолчанию, затем укажите x:elementName вместо elementName.

  • Используйте длинные, уродливые и ненадежные выражения: *[name() = 'elementName']

Здесь представлено преобразование XSLT с использованием вышеописанного метода1.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:a="http://some_url">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:value-of select=
  "/root/items/item/details/a:data/a:weight"/>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется (используя Saxon 6.5.4 или любой другой совместимый процессор XSLT 1.0) на предоставленном XML-документе:

<root>
    <items>
        <item>
            <title>Item</title>
            <details>
                <data xmlns="http://some_url">
                    <length>10</length>
                    <weight>1.2</weight>
                </data>
            </details>
        </item>
    </items>
</root>

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

1.2

Ответ 2

В XPath вам нужно назначить префикс для пространства имен. Как вы это делаете, это зависит от используемого программного обеспечения/библиотеки XPath, но при условии, что вы связываете URI пространства имен http://some_url с префиксом пространства имен someUrl, вы можете изменить выражение XPath следующим образом:

/root/items/item/details/someUrl:data