XSLT:如何将XML节点转换为String

Kal*_*yan 10 xml xslt serialization xpath xml-serialization

<ROOT>
   <A>
      <B>TESTING</B>
   </A>
</ROOT>
Run Code Online (Sandbox Code Playgroud)

XSL:

<xsl:variable name="nodestring" select="//A"/>
<xsl:value-of select="$nodestring"/>
Run Code Online (Sandbox Code Playgroud)

我试图使用XSL将XML节点集转换为字符串.有什么想法吗?

jel*_*irt 12

您需要序列化节点.对你的例子来说最简单的就是这样的

<xsl:template match="ROOT">
  <xsl:variable name="nodestring">
    <xsl:apply-templates select="//A" mode="serialize"/>
  </xsl:variable>
  <xsl:value-of select="$nodestring"/>  
</xsl:template>

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

<xsl:template match="text()" mode="serialize">
  <xsl:value-of select="."/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

上面的序列化程序模板不处理文本节点中的属性,名称空间或保留字符,但概念应该是清楚的.XSLT过程适用于节点树,如果需要访问"标记",则需要序列化节点.


小智 8

基于@jelovirt解决方案,这里有一个更完整的代码:

<xsl:template match="*" mode="serialize">
    <xsl:text>&lt;</xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:apply-templates select="@*" mode="serialize" />
    <xsl:choose>
        <xsl:when test="node()">
            <xsl:text>&gt;</xsl:text>
            <xsl:apply-templates mode="serialize" />
            <xsl:text>&lt;/</xsl:text>
            <xsl:value-of select="name()"/>
            <xsl:text>&gt;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text> /&gt;</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="@*" mode="serialize">
    <xsl:text> </xsl:text>
    <xsl:value-of select="name()"/>
    <xsl:text>="</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>"</xsl:text>
</xsl:template>

<xsl:template match="text()" mode="serialize">
    <xsl:value-of select="."/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)


Dou*_*oug 6

在 XSLT 3.0 版中。有关fn:serialize 的信息,请参阅此 W3 链接。这对我使用 SaxonPE 有用。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<xsl:variable name="output">
    <output:serialization-parameters>
        <output:method value="html"/>
    </output:serialization-parameters>
</xsl:variable>
    <xsl:template match="div">
        <xsl:value-of select="serialize(., $output/output:serialization-parameters)" />
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)


mik*_*key 2

<xsl:template match="A">
  <xsl:variable name="nodes" select="." />
  <xsl:copy-of select="$nodes"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

根据评论更新..

好吧,我以前从来没有完全按照你的需要做过,所以对此持保留态度(我只是即兴发挥)。基本上你需要非常关心两件事:需要转义的字符和空格。在这种情况下, empo在上面的注释中给您的字符串更符合您的需求。以下是使 XSL 输出符合以下要求的一种方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="A">

  <input type="hidden" name="hiddenxml">
    <xsl:attribute name="value">
      <xsl:apply-templates select="." mode="id" />
    </xsl:attribute>
  </input>

</xsl:template>

<xsl:template match="*" mode="id" >
  <xsl:text>&lt;</xsl:text><xsl:value-of select="name(.)" /><xsl:text>&gt;</xsl:text>
  <xsl:apply-templates select="./*" mode="id" />
  <xsl:value-of select="normalize-space(.)" />
  <xsl:text>&lt;/</xsl:text><xsl:value-of select="name(.)" /><xsl:text>&gt;</xsl:text>
</xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

您仍然需要关心其他需要转义的字符,例如“'&我相信您可以使用翻译或替换这些字符