Разрешение подэлементов переменной, которая была передана в шаблон
data.xml:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="myxslt2.xslt"?>
<data>
<foo>Hello</foo>
<bar>World</bar>
<foobar>This is a test</foobar>
</data>
myxslt2.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" version="1.0">
<xsl:output method="html" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" indent="yes"/>
<xsl:variable name="main" select="/data"/>
<xsl:template name="myTemplate">
<xsl:param name="myparam"/>
Inner1:<xsl:value-of select="msxsl:node-set($myparam)"/>
<br/>
Inner2:<xsl:value-of select="msxsl:node-set($myparam)/foobar"/>
</xsl:template>
<xsl:template match="/data">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
HTML STARTS
<br/>
<xsl:variable name="data" select="."/>
Outer1:<xsl:value-of select="$data"/>
<br/>
Outer2:<xsl:value-of select="$data/foobar"/>
<br/>
<xsl:call-template name="myTemplate">
<xsl:with-param name="myparam">
<xsl:value-of select="$data"/>
</xsl:with-param>
</xsl:call-template>
</html>
</xsl:template>
</xsl:stylesheet>
Выход:
HTML STARTS
Outer1: Hello World This is a test
Outer2:This is a test
Inner1: Hello World This is a test
Inner2:
Может ли кто-нибудь объяснить, почему внутреннее не разрешает субэлемент, в то время как внешнее -
1 ответ
Проблема заключается в том, что когда вы передаете переменную $data в качестве параметра myTemplate
<xsl:call-template name="myTemplate">
<xsl:with-param name="myparam">
<xsl:value-of select="$data"/>
</xsl:with-param>
</xsl:call-template>
Поскольку вы используете xsl:value-of здесь, это только передача текстового значения узлов, хранящихся в $data; т.е. параметр является просто одним текстовым узлом. Чтобы сохранить узлы, вам нужно использовать xsl: copy-of
<xsl:call-template name="myTemplate">
<xsl:with-param name="myparam">
<xsl:copy-of select="$data"/>
</xsl:with-param>
</xsl:call-template>
Строго говоря, это прохождение "фрагмента дерева результатов", поэтому вам придется использовать функцию расширения набора узлов, но вам придется изменить ее использование, потому что узел данных здесь не является строго родительским узлом, документ фрагмент
Inner1:<xsl:value-of select="msxsl:node-set($myparam)/data"/>
<br />
Inner2:<xsl:value-of select="msxsl:node-set($myparam)/data/foobar"/>
Но на самом деле вам вообще не нужно здесь использовать набор узлов. Изменить способ вызова шаблона на этот...
<xsl:call-template name="myTemplate">
<xsl:with-param name="myparam" select="$data"/>
</xsl:call-template>
Здесь есть важное отличие. Это больше не фрагмент дерева результатов, а прямая ссылка на входной документ, что означает, что вам вообще не нужно использовать набор узлов.
<xsl:template name="myTemplate">
<xsl:param name="myparam"/>
Inner1:<xsl:value-of select="$myparam"/>
<br />
Inner2:<xsl:value-of select="$myparam/foobar"/>
</xsl:template>