Home > Net >  <xsl:copy-of> does not preserve XML tags
<xsl:copy-of> does not preserve XML tags

Time:12-09

Using Saxon HE 11.4, I'm trying to simply copy some text and preserve XML tags inside of that text. This answer and many others tell me that simply using <xsl:copy-of> is enough. But it doesn't work in my case, <xsl:copy-of> removes all XML tags. Why?

Input XML

<?xml version="1.0" encoding="utf-8"?>
<root>
   <card>
      <k>а</k>
      <body>
         <meaning>
            <trn>возглас удивления</trn>
            <trn>вопрос с оттенком удивления или неудовольствия</trn>            
         </meaning>
      </body>
   </card>
</root>

XSLT file

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:character-map name="escape-square-brackets">
    <xsl:output-character character="[" string="\["/>
    <xsl:output-character character="]" string="\]"/>
  </xsl:character-map>
  
  <xsl:output method="text" encoding="utf-16le" byte-order-mark="yes"/>
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="/root">
    <xsl:result-document href="/Users/xinatanil/Desktop/compiling stuff/abbyy_udahin_kg_ru.dsl" method="text">
      <xsl:text>#NAME "Кыргызско-русский словарь"</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>#INDEX_LANGUAGE "Russian"</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>#CONTENTS_LANGUAGE "Russian"</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      
      <root>
        <xsl:for-each select="card">
          <xsl:value-of select="k"/>
          <xsl:text>&#xa;</xsl:text>
          
          <xsl:for-each select="body/meaning/*">
            <xsl:text> </xsl:text>            
            <xsl:copy-of select="node()"/>
            <xsl:text>&#xa;</xsl:text>            
          </xsl:for-each>
          
          <xsl:text>&#xa;</xsl:text>
        </xsl:for-each>
      </root>
    </xsl:result-document>
  </xsl:template>
  
</xsl:stylesheet>

Expected output

#NAME "Кыргызско-русский словарь"
#INDEX_LANGUAGE "Russian"
#CONTENTS_LANGUAGE "Russian"
а
 <trn>возглас удивления</trn>
 <trn>вопрос с оттенком удивления или неудовольствия</trn>            

Output that I currently get

#NAME "Кыргызско-русский словарь"
#INDEX_LANGUAGE "Russian"
#CONTENTS_LANGUAGE "Russian"

а
 возглас удивления
 вопрос с оттенком удивления или неудовольствия

CodePudding user response:

Start by changing the main output method to xml and removing it from the xsl:result-document element.

Next, if you want copy the already selected elements that are children of meaning, you need to change:

<xsl:copy-of select="node()"/>

to:

<xsl:copy-of select="."/>

Otherwise you're copying the child nodes of those elements.

And you probably want to remove the root wrapper.

And you will also want to suppress the XML declaration.

CodePudding user response:

You have used text as your xsl:output method, that way you don't get the copy of element nodes, just the text nodes. So use e.g. <xsl:output method="xml"/> if your target format is XML and not plain text.

  • Related