开发者

Iterate through XML nodes that have xmlns attribute declared in a XSL

I am working on creating an XSL to format some incoming XML from an API I am integrating. The xml I receive looks like:

<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>

Some of the "item" nodes have the "xmlns" attribute defined, while others do not. When I attempt to iterate through the results in my XSL, it is not finding the nodes that have the xmlns attribute defined.

<xsl:for-each select="item">开发者_JAVA技巧
  <xsl:value-of select="key" />
</xsl:for-each>

I am sort of new to the whole XSL thing, so I'm not sure what I am doing wrong.


You'll need to define the same namespace in your <xsl:stylesheet> definition.

Then:

<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>

Really you should try and use the same namespace for things that are the same.


First off, if you don't understand how XML namespaces work and what they mean, you're going to have no end of problems. This issue you're struggling with is the tip of the iceberg.

That said, you can deal with namespaces the way Kyle Butt suggested, assigning a transform-wide mapping of prefixes to namespaces in the stylesheet element and then using the prefixes in your XPath expression.

But what if you don't know the namespaces? Then you have to use a blunter instrument:

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

Using local-name() ignores namespaces completely. But you can't use it in a node test (which has to be a name like foo or a qualified name like x:foo), you can only use it in a predicate. Which is why the unlovely *[local-name()='foo'] is the only way to do it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜