Итерация по узлам XML, которые имеют атрибут xmlns, объявленный в XSL - PullRequest
0 голосов
/ 25 января 2010

Я работаю над созданием XSL для форматирования некоторого входящего XML из API, который я интегрирую. Xml, который я получаю, выглядит так:

<items>
  <item xmlns="http://www.tempuri.org/Item.xsd">
    <key>value</key>
  </item>
  <item>
    <key>value</key>
  </item>
  <item xmlns="http://www.tempuri.org/Item.xsd">
    <key>value</key>
  </item>
</items>

Некоторые узлы "item" имеют определенный атрибут "xmlns", а другие нет. Когда я пытаюсь перебрать результаты в моем XSL, он не находит узлы, для которых определен атрибут xmlns.

<xsl:for-each select="item">
  <xsl:value-of select="key" />
</xsl:for-each>

Я новичок во всем, что касается XSL, поэтому я не уверен, что делаю неправильно.

Ответы [ 2 ]

1 голос
/ 25 января 2010

Вам необходимо определить то же пространство имен в вашем определении <xsl:stylesheet>.

Тогда:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="http://www.tempuri.org/Item.xsd"
    extension-element-prefixes="exsl"
    encoding="utf-8">

. . .

<xsl:for-each select="item|ns:item">
    <xsl:value-of select="key|ns:key"/>
</xsl:for-each>

На самом деле вы должны попытаться использовать одно и то же пространство имен для одинаковых вещей.

0 голосов
/ 27 января 2010

Прежде всего, если вы не понимаете, как работают пространства имен XML и что они значат, у вас не будет конца проблем.Эта проблема, с которой вы сталкиваетесь, является верхушкой айсберга.

Тем не менее, вы можете иметь дело с пространствами имен так, как предложил Кайл Батт, назначая преобразование префиксов в масштабе преобразования для пространств имен в элементе stylesheetа затем с помощью префиксов в вашем выражении XPath.

Но что, если вы не знаете пространства имен?Затем вы должны использовать более грубый инструмент:

<xsl:for-each select="*[local-name()='item']">
  <xsl:value-of select="*[local-name()='key']"/>
</xsl:for-each>

Использование local-name() полностью игнорирует пространства имен.Но вы не можете использовать его в тесте узла (это должно быть имя типа foo или квалифицированное имя, например x:foo), вы можете использовать его только в предикате.Вот почему милые *[local-name()='foo'] - единственный способ сделать это.

...