使用XSLT将标记中的内容转换为基于文本的字符

时间:2013-01-07 04:30:31

标签: xslt

我需要根据元素中的字符转换下面的XML。我试过下面的XSLT 1.0。在<mo>元素中,&#x007B;&#x007D;应转换为| text {|和|文本} |分别。 {}应转换为| cbo |和| cbc |分别。但我得到'|(text} ||(text {||(text} ||(text {| for the contents in`elements

示例XML:

<chapter xmlns="http://www.w3.org/1998/Math/MathML"><p><math display='block'><mo>{</mo><mo>&#x007B;</mo><mo>&#x007D;</mo><mo>}</mo></math></p></chapter>

XSLT 1.0试过:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()"><xsl:copy><xsl:apply-templates select="@* | node()"/>    
</xsl:copy></xsl:template>
<xsl:template match="m:mo">
<xsl:choose>
<xsl:when test="(.)='&#x007B;'"><xsl:text disable-output-escaping="yes">|(text{|</xsl:text>
</xsl:when>
<xsl:when test="(.)='&#x007D;'"><xsl:text disable-output-escaping="yes">|(text}|</xsl:text>
</xsl:when>
<xsl:when test="(.)='{'"><xsl:text disable-output-escaping="yes">|cbo|</xsl:text></xsl:when>
<xsl:when test="(.)='}'"><xsl:text disable-output-escaping="yes">|cbc|</xsl:text></xsl:when>
</xsl:choose></xsl:template></xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

我无法重现“问题” - 提供的XSLT代码产生的输出不包含以下子字符串:

"|(text}||(text{||(text}||(text{|"

提供的,不可读的代码可以简化为以下简单代码 - 请注意根本不需要DOE:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:m="http://www.w3.org/1998/Math/MathML">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

 <xsl:template match="m:mo">
   <xsl:choose>
    <xsl:when test=". = '&#x007B;'">
     <xsl:text>|(text{|</xsl:text>
    </xsl:when>
    <xsl:when test=". = '&#x007D;'">
     <xsl:text>|(text}|</xsl:text>
    </xsl:when>
    <xsl:when test=". = '{'">
     <xsl:text>|cbo|</xsl:text>
    </xsl:when>
    <xsl:when test=". = '}'">
     <xsl:text>|cbc|</xsl:text>
    </xsl:when>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

原始代码及其等效的可读和简化代码(上图)都产生相同的结果(当我们不考虑缩进或缺少此类代码时):

<chapter xmlns="http://www.w3.org/1998/Math/MathML">
   <p>
      <math display="block">|(text{||(text{||(text}||(text}|</math>
   </p>
</chapter>

我不知道这个结果是“好”还是“坏”,因为OP没有说明他想要产生什么结果,他得到了什么结果,以及为什么他得到的结果不是' “好”。

答案 1 :(得分:1)

  

当实体&#x007B;进来时,它应该转换为|(text {|当charcter {到来时它应该转换为| cbo |。

一旦您的XML通过XML解析器,这两个输入就无法区分。这有点像说你想要以不同的方式处理它们,这取决于作者是用左手还是用右手键入文本 - 它们只是输入相同数据的不同方式。

如果要区分它们,则需要进行某种预处理,以便通过XML解析保留差异。一种方法是使用Andrew Welch的Lexev工具,它与KernowForSaxon集成。但是,我会质疑你的设计;根据这样的词汇差异会使你的系统非常脆弱。