XSL将父节点复制为其自己的父节点

时间:2015-10-14 08:18:26

标签: xslt

我有一个复杂的要求,我需要复制Parent节点并使其成为自己的Parent节点。它现在将成为子节点,并将转义字符。请参阅以下示例:

样品:

<Messages>
<Parameters>
      <Field1>1</Field1>
      <Field2>2</Field2>
</Parameters>
<Parameters>
      <Field3>3</Field3>
      <Field4>4</Field4>
</Parameters>
</Messages>

期望的输出:

<Messages>
<Parameters>
&lt;Parameters&gt;
&lt;Field1&gt;1&lt;/Field1&gt;
&lt;Field2&gt;2&lt;/Field2&gt;
&lt;/Parameters&gt;
</Parameters>
<Parameters>
&lt;Parameters&gt;
&lt;Field3&gt;3&lt;/Field3&gt;
&lt;Field4&gt;4&lt;/Field4&gt;
&lt;/Parameters&gt;
</Parameters>
</Messages>

这可能吗?由于另一个stackoverflow论坛答案,我实际上有用于转义字符的XSL代码。我不确定如何创建父节点。

谢谢大家! 问候, XSL新手

到目前为止我的代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
    <xsl:template match="/">
    <ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
                                <xsl:apply-templates/>
  </ns0:Messages>
    </xsl:template>



<xsl:template match="*">
    <xsl:text disable-output-escaping="no">&lt;</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:apply-templates select="@*"/>
    <xsl:text disable-output-escaping="no">&gt;</xsl:text>
    <xsl:apply-templates select="node()"/>
    <xsl:text disable-output-escaping="no">&lt;/</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text disable-output-escaping="no">&gt;</xsl:text>
</xsl:template>

<xsl:template match="@*">
    <xsl:text disable-output-escaping="no">&#32;</xsl:text>
    <xsl:value-of select="name()" disable-output-escaping="no"/>
    <xsl:text disable-output-escaping="yes">=&amp;quot;</xsl:text>
    <xsl:value-of select="." disable-output-escaping="no"/>
    <xsl:text disable-output-escaping="yes">&amp;quot;</xsl:text>
</xsl:template>
<xsl:template match="text()">
    <xsl:value-of select="."/>
</xsl:template>

 <xsl:template match="ns0:Messages">
  <xsl:apply-templates/>
 </xsl:template>

        </xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

我认为你应该首先检查你的XSLT处理器是否支持一个扩展函数来将树节点序列化为XML,因为这通常比将几个XSLT模板放在一起做得更好。例如,使用像Saxon 9.6这样的XSLT 3.0处理器,您可以简单地使用serialize函数

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">

    <xsl:variable name="ser-params">
        <output:serialization-parameters
               xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
          <output:method value="xml"/>
          <output:version value="1.0"/>
          <output:indent value="yes"/>
          <output:omit-xml-declaration value="yes"/>
        </output:serialization-parameters>
    </xsl:variable>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Parameters">
        <xsl:copy>
            <xsl:value-of select="serialize(., $ser-params/*)"/>
        </xsl:copy>
    </xsl:template>

</xsl:transform>

如果您想使用您的方法,请使用模式,例如

<xsl:template match="Parameters">
  <xsl:copy>
    <xsl:apply-templates select="." mode="serialize"/>
  </xsl:copy>
</xsl:template>

然后输出序列化标记的模板需要定义和使用模式,例如

<xsl:template match="*" mode="serialize">
    <xsl:text disable-output-escaping="no">&lt;</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:apply-templates select="@*"/>
    <xsl:text disable-output-escaping="no">&gt;</xsl:text>
    <xsl:apply-templates select="node()" mode="serialize"/>
    <xsl:text disable-output-escaping="no">&lt;/</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text disable-output-escaping="no">&gt;</xsl:text>
</xsl:template>

<xsl:template match="@*" mode="serialize">
    <xsl:text disable-output-escaping="no">&#32;</xsl:text>
    <xsl:value-of select="name()" disable-output-escaping="no"/>
    <xsl:text disable-output-escaping="yes">=&amp;quot;</xsl:text>
    <xsl:value-of select="." disable-output-escaping="no"/>
    <xsl:text disable-output-escaping="yes">&amp;quot;</xsl:text>
</xsl:template>

可能需要更多更正,但您在样式表中使用了名称空间而未在示例XML中显示任何名称空间,因此无法确定需要更正的位置。