最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to refer in an XSLT to a variable that contains nested XML - Stack Overflow

programmeradmin1浏览0评论

I want to refer to a deeper XML level of a variable that I've defined in an XSLT file. However, when I try to transform my XSD using the XSLT, it always says that my stylesheet is invalid. Only when I refer to de $descriptions without the annotations part, it transforms, but then I get al the descriptions as a result of that variable. Is it possible to refer to an element within the variable?

(I don't really need annotation[1] but a more difficult formula that finds the correct annotation, but this one doesn't work as well.)

<xsl:stylesheet xmlns:xsl=";     xmlns:xs="; version="1.0">

<xsl:variable name="descriptions">
    <annotations>
        <annotation element="Element1">Description for Element1</annotation>
        <annotation element="Element2">Description for Element2</annotation>
        <annotation element="Element3">Description for Element3</annotation>
    </annotations>
</xsl:variable>


<xsl:template match="xs:element">
<xsl:copy>
    <xsl:apply-templates select="@*"/>
        <xsl:variable name="description"     select="$descriptions/annotations/annotation[1]"/>

I tried if my problem is within the namespace, but I really can't find anything to solve or even help it.

I want to refer to a deeper XML level of a variable that I've defined in an XSLT file. However, when I try to transform my XSD using the XSLT, it always says that my stylesheet is invalid. Only when I refer to de $descriptions without the annotations part, it transforms, but then I get al the descriptions as a result of that variable. Is it possible to refer to an element within the variable?

(I don't really need annotation[1] but a more difficult formula that finds the correct annotation, but this one doesn't work as well.)

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

<xsl:variable name="descriptions">
    <annotations>
        <annotation element="Element1">Description for Element1</annotation>
        <annotation element="Element2">Description for Element2</annotation>
        <annotation element="Element3">Description for Element3</annotation>
    </annotations>
</xsl:variable>


<xsl:template match="xs:element">
<xsl:copy>
    <xsl:apply-templates select="@*"/>
        <xsl:variable name="description"     select="$descriptions/annotations/annotation[1]"/>

I tried if my problem is within the namespace, but I really can't find anything to solve or even help it.

Share Improve this question edited Jan 17 at 17:06 Joost van de Ven asked Jan 17 at 17:05 Joost van de VenJoost van de Ven 112 bronze badges 3
  • If you are using an XSLT 1 processor then that variable is a result tree fragment (RTF), you can't use XPath on it to select anything inside unless you first convert the result tree fragment to a node set with an extension function like exsl:node-set($descriptions)/annotations/annotation. The support of exsl:node-set is rather good but some older Microsoft implementations (all version of MSXML, the obsolete System.Xml.Xsl.XslTransform from .NET) only support a similar extension function in a different, MS namespace. – Martin Honnen Commented Jan 17 at 17:09
  • See previous answers like stackoverflow/questions/17616339/… – Martin Honnen Commented Jan 17 at 17:14
  • Are you actually constrained to use XSLT 1.0? It's been superseded by much more powerful versions for many years. – Michael Kay Commented Jan 17 at 20:37
Add a comment  | 

2 Answers 2

Reset to default 2

Instead of using a variable, you can write down nested XML in a top-level stylesheet element (with an external namespace, like the XMLSchema one in your case). This has the advantage that it can be selected (into a variable, for example) as a proper node without having to convert a result-tree fragment into a nodeset, which always requires some extension in XSLT 1.0.

The trick is to use document('') to select the root of the stylesheet itself.

<xsl:stylesheet
  xmlns:xsl="http://www.w3./1999/XSL/Transform"
  xmlns:xs="http://www.w3./2001/XMLSchema" version="1.0">
  <xs:descriptions>
    <annotations>
      <annotation element="Element1">Description for Element1</annotation>
      <annotation element="Element2">Description for Element2</annotation>
      <annotation element="Element3">Description for Element3</annotation>
    </annotations>
  </xs:descriptions>
  <xsl:variable name="descriptions"
    select="document('')/*/xs:descriptions" />
  <xsl:template match="/">
    <xsl:value-of select="$descriptions/annotations/annotation[1]" />
  </xsl:template>
</xsl:stylesheet>

With XSLT 1.0 you can use the document() function with an empty URI to have the stylesheet load itself as an XML document (XSLT is XML), and then XPath to the variable and address the desired content:

<xsl:variable name="description" select="document('')/xsl:stylesheet/xsl:variable[@name='descriptions']/annotations/annotation[1]"/>
发布评论

评论列表(0)

  1. 暂无评论