Convert mixed XML nodes with output disabled

Variations on this have been published, but I could not find any base case address. I thought it would be nice to have a canonical answer to the simplest version of the problem. This question suggests xslt 1.0.

I have an XML document containing mixed nodes, for example:

<paragraph>
     This is some text that is <bold> bold </bold> 
     and this is some that is <italic> italicized. </italic>
</paragraph>

I would usually use a transform that looks something like this:

<xsl: template match = "bold">
    <b><xsl:apply-templates/> </b>
</ xsl: template>
<xsl: template match = "italic">
    <i><xsl:apply-templates/> </i>
</ xsl: template>
<xsl: template match = "paragraph">
    <p><xsl:apply-templates/> </p>
</ xsl: template>

which works fine until I want to use disable-output-escaping = "yes", which is an xsl: value-of attribute. Is there a way to select the text part of the mixed node to which I can apply the value regardless of the embedded nodes?

This, of course, does not work, because I will lose the child nodes:

<xsl: template match = "paragraph">
    <p> <xsl: value-of select = "." disable-output-escaping = "yes" /> </p>
</ xsl: template>

, , , , XML, XML () , XML- > XSLT- > HTML ( ).

+3
2

, , (disable-output-escaping="yes"), (<bold> to <b> ..)

:

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

  <xsl:template match="paragraph">
    <p>
      <xsl:apply-templates mode="literal" />
    </p>
  </xsl:template>

  <!-- literal templates (invoked in literal mode) -->
  <xsl:template match="bold" mode="literal">
    <b><xsl:apply-templates mode="literal"/></b>
  </xsl:template>
  <xsl:template match="italic" mode="literal">
    <i><xsl:apply-templates mode="literal"/></i>
  </xsl:template>
  <xsl:template match="text()" mode="literal">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>

  <!-- normal templates (invoked when you don't use a template mode) -->
  <xsl:template match="bold">
    <b><xsl:apply-templates /></b>
  </xsl:template>
  <xsl:template match="italic">
    <i><xsl:apply-templates /></i>
  </xsl:template>

</xsl:stylesheet>
+2

( node); : XSLT node

0

Source: https://habr.com/ru/post/1716116/


All Articles