[英]How do I serialize output from a node-set in xslt 1.0?
I am working with some XML inside of XSLT.我正在使用 XSLT 中的一些 XML。 I want to save a section of it in a content node.我想将它的一部分保存在内容节点中。 I left the CDATA node out of this example.我在这个例子中没有使用 CDATA 节点。
When I grab the xml like this it's escaped ie.当我像这样抓取 xml 时,它被转义了,即。 <
= < = <
<content name="test”>
<xsl:copy-of select="//content[@name='something']/node()" />
</content>
But I need to do some processing on the data before I store it in a content node.但是在将数据存储到内容节点之前,我需要对数据进行一些处理。 I have an xsl:for-each call and it loops saving sections.我有一个 xsl:for-each 调用,它循环保存部分。 However, when I call a similar command I can't get the XML to escape.但是,当我调用类似的命令时,我无法让 XML 转义。
<xsl:for-each select="exsl:node-set($xml)//data">
<content name="test">
<xsl:copy-of select="./node()" />
</content>
I've put CDATA nodes around it and outputted the content, but then I have issues in the system with double escaping.我已经在它周围放置了 CDATA 节点并输出了内容,但是我在系统中遇到了双重转义问题。 I really need this copy-of call to output escaped XML.我真的需要这个调用副本来输出转义的 XML。
I really want something like:我真的想要这样的东西:
<content name="test">
<data>Some data<\data>
</content>
Input would be something like this:输入将是这样的:
<root>
<data>Some data</data>
<data>more data</data>
</root>
This a simplification of the data.这是数据的简化。 There would be additional xml nodes in the data node.数据节点中会有额外的 xml 节点。
Evan Lenz has an XSLT 1 based implementation of XML serialization at http://lenzconsulting.com/xml-to-string/ : if you use that you have eg Evan Lenz 在http://lenzconsulting.com/xml-to-string/有一个基于 XSLT 1 的 XML 序列化实现:如果你使用它,你有例如
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>
<xsl:output indent="yes" cdata-section-elements="content"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<content>
<xsl:apply-templates select="." mode="xml-to-string"/>
</content>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPzifpn/4 https://xsltfiddle.liberty-development.net/pPzifpn/4
If the processor is libxslt then it might allow you to implement an extension function, for instance PHP allows you to call PHP functions and the DOMDocument
in PHP has a saveXML
function to serialize, so you can call that from XSLT:如果处理器是 libxslt,那么它可能允许您实现扩展功能,例如 PHP 允许您调用 PHP 函数,而 PHP 中的DOMDocument
有一个用于序列化的saveXML
函数,因此您可以从 XSLT 调用它:
<?php
function serializeNode($node) {
return $node[0]->ownerDocument->saveXML($node[0]);
}
$xml = <<<EOT
<root>
<data>Some data</data>
<data>more data</data>
</root>
EOT;
$xsl = <<<EOT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl"
exclude-result-prefixes="php"
version="1.0">
<xsl:output indent="yes" cdata-section-elements="content"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<content>
<xsl:value-of select="php:function('serializeNode', .)"/>
</content>
</xsl:template>
</xsl:stylesheet>
EOT;
$doc = new DOMDocument();
$doc->loadXML($xml);
$proc = new XSLTProcessor();
$proc->registerPHPFunctions('serializeNode');
$sheet = new DOMDocument();
$sheet->loadXML($xsl);
$proc->importStylesheet($sheet);
echo $proc->transformToXml($doc);
?>
<!-- XSL 1.0 -->
<xsl:template match="*|@*|text()|comment()" mode="copy">
<xsl:param name="_-"><!--<">-do-not-modify-this--></xsl:param>
<xsl:variable name="ch" select="document('')//*[@name='_-']/comment()"/>
<xsl:variable name="lt" select="substring($ch, 1, 1)"/>
<xsl:variable name="qq" select="substring($ch, 2, 1)"/>
<xsl:variable name="gt" select="substring($ch, 3, 1)"/>
<xsl:choose>
<xsl:when test="self::*">
<xsl:value-of select="concat($lt, name())"/>
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:variable name="ns" select="namespace-uri()"/>
<xsl:if test="$ns and not(ancestor::*[namespace-uri() = $ns])">
<xsl:variable name="pf" select="substring-before(name(), ':')"/>
<xsl:value-of select="concat(' xmlns:', $pf, '=', $qq, $ns, $qq)"/>
</xsl:if>
<xsl:value-of select="$gt"/>
<xsl:apply-templates select="*|text()|comment()" mode="copy"/>
<xsl:value-of select="concat($lt, '/', name(), $gt)"/>
</xsl:when>
<xsl:when test="self::comment()">
<xsl:value-of select="concat($lt, '!--', ., '--', $gt)"/>
</xsl:when>
<xsl:when test="self::text()"><xsl:value-of select="."/></xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(' ', name(), '=', $qq, ., $qq)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.