XML-XSLT-Escape特殊字符

XML-XSLT-Escape特殊字符,xml,xslt,saxon,Xml,Xslt,Saxon,这个问题与我发布的另一个问题有关,我仍在努力解决,这里:,但由于这是一个更简单的问题,我决定发表一篇关于它的新文章,使这个问题更“可读”,并对这篇文章的未来读者更有用 我有以下XML文件: <?xml version="1.0" encoding="UTF-8"?> <entry> <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]>

这个问题与我发布的另一个问题有关,我仍在努力解决,这里:,但由于这是一个更简单的问题,我决定发表一篇关于它的新文章,使这个问题更“可读”,并对这篇文章的未来读者更有用

我有以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<entry>
    <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
</entry>
但是,当我尝试使用不同的输入时,我在我的帖子中使用了我以前引用过的输入,这是:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
    <text-prop name="displayName">PersonTemplate</text-prop>
    <setup>
        <simple-master-page name="MasterPage" id="2">
            <footer>
                <text id="3">
                    <prop name="contentType">html</prop>
                    <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
                </text>
            </footer>
        </simple-master-page>
    </setup>
    <body>
        <table id="4">  
            <column id="17"/>
            <column id="18"/>
            <column id="19"/>
            <header>
                <row id="5">
                    <cell id="6">
                        <label id="20">
                            <text-prop name="text">NameTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="7">
                        <label id="21">
                            <text-prop name="text">CityTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="8">
                        <label id="22">
                            <text-prop name="text">AgeTitle</text-prop>
                        </label>
                    </cell>
                </row>
            </header>
            <detail>
                <row id="9">
                    <cell id="10"/>
                    <cell id="11"/>
                    <cell id="12"/>
                </row>
            </detail>
        </table>
    </body>
</report>
声明输入XML在XSLT文件中使用的命名空间

我得到了正确的
,但是现在,因为我有更多的
元素,所以输出在每个
元素中都带有
标记,如下所示:

 <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" cdata-section-elements="text-prop"/>
    <xsl:strip-space elements="*"/>

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

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
   <text-prop name="displayName"><![CDATA[PersonTemplate]]></text-prop>
   <setup>
      <simple-master-page name="MasterPage" id="2">
         <footer>
            <text id="3">
               <prop name="contentType">html</prop>
               <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
            </text>
         </footer>
      </simple-master-page>
   </setup>
   <body>
      <table id="4">
         <column id="17"/>
         <column id="18"/>
         <column id="19"/>
         <header>
            <row id="5">
               <cell id="6">
                  <label id="20">
                     <text-prop name="text"><![CDATA[NameTitle]]></text-prop>
                  </label>
               </cell>
               <cell id="7">
                  <label id="21">
                     <text-prop name="text"><![CDATA[CityTitle]]></text-prop>
                  </label>
               </cell>
               <cell id="8">
                  <label id="22">
                     <text-prop name="text"><![CDATA[AgeTitle]]></text-prop>
                  </label>
               </cell>
            </row>
         </header>
         <detail>
            <row id="9">
               <cell id="10"/>
               <cell id="11"/>
               <cell id="12"/>
            </row>
         </detail>
      </table>
   </body>
</report>
 <xsl:template match="setup/text-prop">
  <xsl:copy>
    <setup>
      <text-prop>
         <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
         <xsl:value-of>whatever</xsl:value-of>
         <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
      </text-prop>
    </setup>
   <xsl:copy>
   <xsl:apply-templates/>
  </xsl:template>

html
新日期()]>
不是像我想要的那样获取输出XML,而是与输入XML完全相同

<?xml version="1.0" encoding="UTF-8"?>
    <entry>
       <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]> </text-prop>
    </entry>
我知道我可能无法使用
xsl:output
cdata部分元素


注意:在我的输入XML中,我只有一个
元素,其中包含值,所有其他元素都包含普通文本。

由于XSLT总是首先匹配最精确的模板,所以您可以只匹配setup/text prop,并专门为此部分创建CDATA块。 然后,根据XML,可以使用应用模板继续匹配其他元素

它可能看起来像这样:

 <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" cdata-section-elements="text-prop"/>
    <xsl:strip-space elements="*"/>

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

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
   <text-prop name="displayName"><![CDATA[PersonTemplate]]></text-prop>
   <setup>
      <simple-master-page name="MasterPage" id="2">
         <footer>
            <text id="3">
               <prop name="contentType">html</prop>
               <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
            </text>
         </footer>
      </simple-master-page>
   </setup>
   <body>
      <table id="4">
         <column id="17"/>
         <column id="18"/>
         <column id="19"/>
         <header>
            <row id="5">
               <cell id="6">
                  <label id="20">
                     <text-prop name="text"><![CDATA[NameTitle]]></text-prop>
                  </label>
               </cell>
               <cell id="7">
                  <label id="21">
                     <text-prop name="text"><![CDATA[CityTitle]]></text-prop>
                  </label>
               </cell>
               <cell id="8">
                  <label id="22">
                     <text-prop name="text"><![CDATA[AgeTitle]]></text-prop>
                  </label>
               </cell>
            </row>
         </header>
         <detail>
            <row id="9">
               <cell id="10"/>
               <cell id="11"/>
               <cell id="12"/>
            </row>
         </detail>
      </table>
   </body>
</report>
 <xsl:template match="setup/text-prop">
  <xsl:copy>
    <setup>
      <text-prop>
         <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
         <xsl:value-of>whatever</xsl:value-of>
         <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
      </text-prop>
    </setup>
   <xsl:copy>
   <xsl:apply-templates/>
  </xsl:template>

![CDATA[
无论什么
]]

首先,CDATA不是XDM数据模型的一部分,它被认为纯粹是转义特殊字符的另一种方式:两种形式

<X><![CDATA[<>]]></X>
]>


被认为是完全可互换的

这意味着您的样式表无法区分在输入中使用了这两个选项中的哪一个:无法知道

xsl:output上的cdata section elements属性为您提供了对输出中使用哪个表单的一些控制,但正如您所发现的,它并没有提供完全的控制


通过使用禁用输出转义、角色映射或Andrew Welch的lexev实用程序,您可以获得更多的控制,但所有这些解决方法都提出了一个问题:为什么它如此重要?如果有人根据结果文档是否使用CDATA对其进行了不同的处理,那么他们滥用了XML,需要重新教育。

为什么这对您来说是一个大问题?如果在其他节点中没有cdata,那么也将是相同的。您与更改的其他元素无关。为了得到它,我尝试了几种选择,但都做不到。希望其他人能解决这个问题,我只希望其中一个节点有CDATA,就像在输入XML文件中一样。但当我使用cdata节元素属性时,它会应用于所有标记,但我只希望它应用于标记内部的标记。我尝试过这样做(请参见XSLT FIDLE):。我试图首先复制整个输入XML文件,然后在setup/text-prop标记中更改该值。它不起作用,因为我不太确定如何使用标识转换来复制整个输入XML文件,然后对其应用更改。这几乎是正确的,但该行的输入是:new Date()]>,您提供的XSLT prodoces:new Date()]>,这意味着属性名丢失。我这样解决了它,但它不是很优雅。。。嗨,不错。你也可以只匹配text/text-prop,现在我看到了XML,我想你也可以使用text-prop[@name='content'],但我只能访问我的手机,所以不容易验证:)我刚刚检查过,将要使用我的XML的“系统”接受它,或者是has]]>。无论如何,我解决了这个问题,就像我在XSLT提琴中的@TimC注释中所显示的那样。基本上,我认为我必须像传递CDATA一样传递它,但正如您所说,它是可互换的,“系统”接受任何一种方式。谢谢你的回答和信息!现在我的问题是,在执行标识转换之后,向XML添加新的元素/标记。。。我在这里发布了一个与此相关的问题:这个问题还包括处理document()函数,这对我来说是一件全新的事情。
<X><![CDATA[<>]]></X>
<X>&lt;&gt;</X>