выбрать узел с xmlns?

Я пытаюсь выбрать все ссылки в документе xhtml в xsl. Некоторые теги привязки содержат объявление пространства имен xmlns="http://www.w3.org/1999/xhtml". Эти не выбраны. например с этим xml-документом:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<root>
<item>
this iz sum text and it haz sum <a xmlns="http://www.w3.org/1999/xhtml" href="http://cheezburger.com/">linx</a> in it.
Teh linx haz piks of <a href="http://icanhascheezburger.com/">kittehs</a> in dem.
</item>
</root>

и этот xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<dl>
<xsl:for-each select="//root/item/a">
    <dd><xsl:value-of select="."/></dd>
    <dt><xsl:value-of select="@href"/></dt>
</xsl:for-each>
</dl>
</html>
</xsl:template>
</xsl:stylesheet>

Выбрана только вторая ссылка. Может кто-нибудь объяснить, что здесь происходит и как я могу это исправить?


person Nick Van Brunt    schedule 04.10.2010    source источник


Ответы (2)


Если вам нужны оба узла, находящиеся в разных пространствах имен, используйте:

/root/item/*[local-name() = 'a']

Однако это должно происходить редко, обычно вам нужен узел только из одного пространства имен:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:example="http://www.w3.org/1999/xhtml"
  >
....
<xsl:for-each select="/root/item/example:a">
person Wrikken    schedule 04.10.2010
comment
это работает - спасибо. проблема здесь в том, что не все ссылки помечены пространством имен. - person Nick Van Brunt; 05.10.2010
comment
Установка правильного пространства имен по умолчанию в теге таблицы стилей (xmlns="http://www.w3.org/1999/xhtml") должна работать, чтобы заставить /root/item/a выбирать все элементы, если другие «анонимные» узлы также должны находиться в этом пространстве имен. - person Wrikken; 05.10.2010
comment
Это последнее объявление пространства имен полезно для вывода, а не для выбора. XSLT 2.0 имеет атрибут xpath-default-namespace в этом отношении. - person ; 05.10.2010
comment
@Alejandro: Черт, ты прав, я не сразу подумал. Хороший совет ОП, если все узлы должны находиться в одном пространстве имен, - следовать вашему совету :) - person Wrikken; 05.10.2010

Элементы a находятся в двух разных пространствах имен: пространстве имен по умолчанию и пространстве имен xhtml. Если вы переместите XPath за пределы форматирования xhtml, вы можете использовать оба пространства имен для поиска:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <xsl:variable name="links" xmlns:xhtml="http://www.w3.org/1999/xhtml"
                  select="//root/item/(a | xhtml:a)"/>

    <html xmlns="http://www.w3.org/1999/xhtml">
      <dl>
        <xsl:for-each select="$links">
          <dd><xsl:value-of select="."/></dd>
          <dt><xsl:value-of select="@href"/></dt>
        </xsl:for-each>
      </dl>
    </html>
  </xsl:template>

</xsl:stylesheet>
person Harold L    schedule 04.10.2010