调用 XSLT 模板并将所有输出保存到变量 [英] Call XSLT template and save all output to variable

查看:24
本文介绍了调用 XSLT 模板并将所有输出保存到变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想调用和模板并将输出保存到变量中.我想保存 ALL 的输出,包括 HTML 标记,但事实并非如此.

以这个简单的 XSLT 为例:

<xsl:template name="演示"><p>只是一个测试</p></xsl:模板>

这个简单的模板会输出

Just a test

到HTML页面.如果我查看页面源代码,我会看到(当然).现在以使用相同模板的这个例子为例,但我想将输出保存到一个变量,而不是仅仅输出到 HTML:

<xsl:call-template name="演示"></xsl:变量><xsl:value-of select="$test"/><xsl:template name="演示"><p>只是一个测试</p></xsl:模板>

查看变量显示现在唯一的输出是Just a test.

HTML 标记去哪儿了?我希望能够将调用模板的输出保存到变量中,但我也需要 HTML 标记.

在调用这样的模板时,有没有办法避免丢失 HTML 标签?有没有不同的方式来编写我的模板?也许我缺少一个设置?我试过 disable-escape-encoding,但这没什么区别(至少在 Safari 中).

我更喜欢使用该模板来满足这两种需求:我希望能够调用它并将输出显示在 HTML 页面中以供查看.我还希望能够将调用包装在一个变量中,但重要的是两个调用方法都包括模板中指定的所有 HTML 标记/标记.

到目前为止,我已经尝试了两个已发布的答案,但是 copy-of 给了我与 value-of 相同的结果.实际上,我没有使用 value-of,我只是展示了如何复制问题.这是对我正在尝试做的事情的更彻底的解释.

有一个样式表,用于转换从 REST 响应接收到的相当大的 XML.样式表的输出方法设置为 html.

此样式表中的一个模板对如何在表格中显示多达 4 行的数据进行了大量决策.有两列,一列是标签,一列是数据.

所做的决策包括标签的文本是什么以及类别——有时标签是绿色,有时是红色等.数据列可以包含文本和/或数字.有些文本可能是粗体,有些可能是彩色的.有很多先决条件决定了这些属性.

如果我要显示单个项目的详细信息,我会使用此模板完成,但其中一个项目可以选择多个属性.例如,可能有尺寸和颜色.根据用户选择的尺寸或颜色,价格可能不同,特定商品可能缺货,如果价格不同,则用户节省的费用也不同.不同的商品可能免运费,也可能只提供预购.有很多属性.

所以我有一个模板,它对所有这些先决条件进行了任何化处理并构建了一个 填充了相当简单的文本和由一些不那么简单的逻辑派生的数据.

我已经模块化了这个模板,这样我就可以为任何一个项目调用它.它是参数化的,所以我可以指定标签文本、数据、类和其他一些东西.

当网页加载时,默认/主要项目与一般信息一起显示 - 例如价格范围和节省范围等.

但是当用户选择颜色或尺寸时,需要使用正确的数据更新这些表格行.我已经处理了来自 XML 的数据,并且发出另一个服务器请求的成本非常高,所以我所做的是创建一个 JSON 字符串数组,其中包含所有不同类型项目的所有数据.我将此 JSON 保存在隐藏输入控件的 value 属性中.是的,还有其他方法可以做到这一点,但这行得通,而且对我来说似乎是可以管理的.

由于创建这些表行的逻辑在服务器上的样式表中,我对所有项目执行所有这些逻辑,然后将计算出的字符串传递给客户端.下面是一个示例:

然后我有一个小的 JQuery 脚本,每当用户更改下拉列表选择或更改属性时都会触发该脚本.该脚本解析上述 JSON 并确定当前配置的 ProductID 是什么.

注意:如果我像这样散布双引号,输入控件的 value 属性将无效,因此它们实际上都是 &quot;.为了便于查看,我在这里显示了双引号.

一旦 ProductID 被确定,页面就会更新,其中包含许多不同的详细信息,如本编辑前面所述.这些细节来自我创建的另一个 JSON 对象——同样,因为所有产品细节在 XSLT 样式表中都是已知的,这就是我创建 JSON 字符串数组的地方.

如您所见,上面隐藏的输入有一个 value 属性,其中包含一个包含 HTML 标记的 JSON 对象.我见过这项工作,但为了让 JSON 正常工作,我必须转义所有标签.& 符号必须是 &amp;,然后是 &lt;, &gt; 并且用反斜杠转义所有引号.我已经按照这种方式对它进行了编码并且它可以工作 - 尽管看起来很讨厌,但它可以工作并且它可以防止我不得不往返于服务器 - 它可以防止我将所有逻辑放在客户端上创建这些字符串.

这些都与我遇到的问题没有任何关系,但我希望摆脱 JSON 和 XSL/XML 教授的所有评论,他们挑战我在其中使用 JSON 和 XSLT(或 HTML)一句话...

现在,我希望我可以(非常简单地)展示我遇到的确切问题.首先,它与 JSON 的关系非常小.它实际上与使用 xsl:value-of 而不是 xsl:copy-of 无关.

这里是我使用包含 JSON 字符串的 value 属性创建隐藏输入字段的地方:

<xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute><xsl:attribute name="type"><xsl:text>隐藏</xsl:text></xsl:attribute><xsl:attribute name="runat"><xsl:text>服务器</xsl:text></xsl:attribute><xsl:attribute name="value"><xsl:text>[</xsl:text><xsl:for-each select="Items/Item"><xsl:call-template name="JSONItemDetails"><xsl:with-param name="offerNode" select="Offers"/><xsl:with-param name="lastitem" select="position() = last()"/></xsl:call-template></xsl:for-each><xsl:text>]</xsl:text></xsl:attribute></input><xsl:template name="JSONItemDetails"><xsl:param name="offerNode" select="."/><xsl:param name="attributesNode" select="ItemAttributes"/><xsl:param name="listprice" select="0"/><xsl:param name="lastitem" select="false()"/><!-- 产品 ID --><xsl:text>{</xsl:text><xsl:text>&quot;ProductID&quot;:</xsl:text><xsl:text>&quot;</xsl:text><xsl:value-of select="./ProductID"/><xsl:text>",</xsl:text><xsl:for-each select="msxml:node-set($offerNode)"><!-- 标题--><xsl:text>&标题":&​​lt;/xsl:text><xsl:text>&quot;</xsl:text><xsl:call-template name="escapeQuote"><xsl:with-param name="pText"><xsl:call-template name="title"><xsl:with-param name="node" select="$attributesNode"/></xsl:call-template></xsl:with-param></xsl:call-template><xsl:text>",</xsl:text><!-- 标价--><xsl:text>"ListPrice&quot;:</xsl:text><xsl:text>&quot;</xsl:text><xsl:call-template name="escapeQuote"><xsl:with-param name="pText"><xsl:call-template name="DataTableRow"><xsl:with-param name="label" select="'List Price:'"/><xsl:with-param name="data" select="./Price/FormattedPrice"/><xsl:with-param name="dataid" select="'listprice'"/></xsl:call-template></xsl:with-param></xsl:call-template><xsl:text>&quot;</xsl:text></xsl:for-each><xsl:text>}</xsl:text><xsl:if test="$lastitem != true()"><xsl:text>,</xsl:text></xsl:if>

DataTableRow 模板做了很多事情,主要提供一致性,但也清理所有用于创建行和列的杂散 HTML 标签.这是那个模板.

<xsl:param name="label" select="''"/><xsl:param name="data" select="''"/><xsl:param name="dataid" select="''"/><xsl:param name="concat" select="''"/><xsl:param name="class" select="''"/><tr><xsl:when test="$data = not(string(.))"><xsl:attribute name="style"><xsl:text>display:none</xsl:text></xsl:attribute></xsl:when><xsl:否则><xsl:attribute name="style"><xsl:text>display:block</xsl:text></xsl:attribute></xsl:否则></xsl:选择><!-- 标签列--><td><div><xsl:when test="$class = 'bigmaroon'"><xsl:attribute name="class"><xsl:text>数据标签栗色</xsl:text></xsl:attribute></xsl:when><xsl:否则><xsl:attribute name="class"><xsl:text>数据标签</xsl:text></xsl:attribute></xsl:否则></xsl:选择><xsl:value-of select="$label"/>

</td><!-- 数据列--><td class="datainfo"><xsl:attribute name="id"><xsl:value-of select="$dataid"/></xsl:attribute><xsl:when test="$class = 'strike'"><罢工><xsl:value-of select="$data"/></罢工><xsl:value-of select="$concat"/></xsl:when><xsl:when test="$class = 'maroon'"><span class="栗色"><xsl:value-of select="$data"/></span><xsl:value-of select="$concat"/></xsl:when><xsl:when test="$class = 'bigmaroon'"><span class="bigmaroon"><xsl:value-of select="$data"/></span><xsl:value-of select="$concat"/></xsl:when><xsl:否则><xsl:value-of select="$data"/><xsl:value-of select="$concat"/></xsl:否则></xsl:选择></td></tr>

DataTableRow 模板有一些逻辑,每次我需要编写这些行之一时都会很麻烦.首先,所有这些行都必须存在于 HTML 中.如果没有数据,则将它们设置为 display:none 样式.这很重要,因为除非有一个有效的选择器,否则我将无法用我的 JQuery 脚本中的数据填充它们......

问题是,毕竟,当像这样直接调用 DataTableRow 时,它工作得很好:

在上面的调用中,HTML标签全部输出到我的网页.他们看起来不错,他们的班级和风格是正确的.我可以在我的模板中的任何地方这样调用它,它工作得很好.我确信这里或那里存在一个错误,我可能会看到更好/更有效的编码方式,但它基本上适用于 HTML.

问题:当我在上面构建隐藏的输入字段时,我无法获得任何 HTML 标签.存储在我的 JSON 字符串中的唯一值是 innerhtml.从 JSONItemDetails 模板调用 DataTableRow 而不是获取以下结果:

<tr><td>一些标签</td><td>一些数据</td></tr>

我得到的结果

Some LabelSome Data

问这样一个简单的问题需要大量的信息,但我收到的回复似乎暗示如果我在 XSLT/HTML 中处理 JSON,我做的事情就不对.

有人能帮我解决问题吗?为什么我在 JSONItemDetails 中调用 DataTableRow 的输出中的 HTML 标签来创建我的 JSON 字符串?

编辑 #2:

我的代码中有几件事情导致了 HTML 标签被剥离的问题.我终于知道是什么导致了这个问题,现在我一直在想办法解决这个问题.以下是附加说明.

我可以确认,xsl:value-of 正在从模板调用的输出中剥离我的 HTML 标记.xsl:copy-of 向我展示了我期望的标签.这对我了解问题所在有很大帮助,但也让我能够识别其他问题.

  1. xsl-copy 不能用于标签的 value= 属性下的输出.我明白为什么,但如果我朝着我要去的方向前进,我对如何处理这个问题一无所知.
  2. 即使我找到了 #1 的解决方案,我也必须弄清楚如何转义 HTML 标记中的双引号.即:双引号在 value= 属性中无效.我知道撇号会起作用,但这些双引号是通过在某些标签下使用 xsl:attribute 来指定类或偶尔样式而创建的.我有一个模板用反斜杠转义双引号,但调用它也会去掉我的 HTML 标签,我不明白为什么 - 所以我不知道如何修复它.我将在下面发布此模板的代码.

如果我有解决上述 2 个问题的方法,我可以按照我一直在走的方向前进,但我愿意听取有关为什么我不应该在我的 JSON 中混合数据和显示的建议.

>

我将两者混合使用是因为我不喜欢将显示逻辑放在我的 JQuery 脚本中的想法.我希望我的脚本对这种逻辑保持无知.在 JQuery 中,使用这些 JSON 对象深入到 ProductID 并替换表行很简单,如下所示:

 var details = $.parseJSON($("#[id*='hfDetails']").val());varfilteredDetails = $.grep(details, function (n) {返回 n.ProductID == ProductID;});如果 (filteredDetails.length > 0) {var 产品 = 过滤详细信息 [0];$("div#title").html(product.Title);$("td#listprice").parent().html(product.ListPrice);$("td#price").parent().html(product.Price);$("td#yousave").parent().html(product.YouSave);}

如果我按照 Dimitre 的建议从我的 JSON 字符串中删除显示,突然之间我必须在我的 jquery 脚本中放入很多逻辑,不仅要提供 <tr><td> 格式化(类),以及包装实际数据的逻辑,如 、颜色规范和字体大小,甚至特定的表格行是 display:block 还是 display:none.我绝对不想在客户端的 JQuery 脚本中编写任何逻辑.

在我的 XSLT 模板中使用一个非常简单的 xsl:for-each 在服务器上创建这些字符串并将结果填充到我的 JSON 对象中,以便我可以使用上述脚本.不可否认,数据很难看.

另一个注意事项,无论我是否将显示与数据分开,如果只有一个项目具有单一的显示可能性,仍然需要我用来处理我的 XML 的当前 XSLT 模板.如果只有一个产品,JSON 不会出现在图片中,因为页面上没有显示用于更改产品属性(颜色、尺寸等)的控件.

我绝对想把这个正确"编码,所以我当然很感激听到经验.我只是不认为任何人可以有效地建议我支持或反对最终结果,而不知道让我到达那里的所有考虑

这是我用来转义双引号的模板: