XSL-Transformation:转义标记并保留此标记内的属性

时间:2017-10-25 11:59:32

标签: xslt-1.0 xslt-2.0

我是一个关于xsl转换的绝对初学者,我有一个问题,你们可以帮助我。我有以下xml块:

<Metrics>
    <Metric name="DocAmount" value="123.21" currency="GBP" type="Total"/>
    <Metric name="Invoices" value="113.21" currency="GBP" type="Total"/>
    <Metric name="Credit" value="10.00" currency="GBP" type="Total"/>
</Metrics>

我必须逃避“&lt;”和“&gt;”来自内部元素“度量”并同时保留所有属性及其值=&gt;我想要这个:

<Metrics>
    &lt;Metric name="DocAmount" value="123.21" currency="GBP" type="Total"/&gt;
    &lt;Metric name="Invoices" value="113.21" currency="GBP" type="Total"/&gt;
    &lt;Metric name="Credit" value="10.00" currency="GBP" type="Total"/&gt;
</Metrics>

我已经在stackoverflow中搜索了这个,并找到了逃避“&lt;”的方法和“&gt;”但是我的xsl模板没有复制属性,我在这里得到了这个:

<Metrics>
        &lt;Metric&gt;&lt;/Metric&gt;
        &lt;Metric&gt;&lt;/Metric&gt;
        &lt;Metric&gt;&lt;/Metric&gt;
</Metrics>

为了得到这个,我使用了以下xsl模板定义:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/> 

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

   <xsl:template match="Metric">      
        <xsl:value-of select="concat('&lt;',name(),'&gt;',.,'&lt;/',name(),'&gt;')" />
   </xsl:template> 

</xsl:stylesheet>

有人可以帮我设置正确的xsl模板吗? 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

由于您的问题被标记为XSLT 2,而且这些天我们有XSLT 3和主要的XSLT 2.0实现,如Saxon 9与Saxon 9.8或Altova与Altova 2017或2018已更新以支持XSLT 3我认为最简单和最优雅的解决方案是转移到XSLT 3并使用XPath 3 serialize函数:

<xsl:template match="Metric">
  <xsl:value-of select="serialize(.)"/>
</xsl:template>

由于您的评论表明您的输入中有命名空间,因此您不希望序列化,您可以使用

<xsl:template match="Metric">
  <xsl:variable name="copy" as="element(Metric)"><xsl:copy-of select="." copy-namespaces="no"/></xsl:variable>
  <xsl:value-of select="serialize($copy)"/>
</xsl:template>