【问题标题】:XSL PI names starting with XML are reserved保留以 XML 开头的 XSL PI 名称
【发布时间】:2017-03-18 15:29:27
【问题描述】:

我正在解析 XML 文档以创建另一个 XML 文档。

文档看起来像这样:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="02_tranformation.xsl"?>
<ROWSET>
 <ROW>
  <SRC_TABLE>myTable</SRC_TABLE>
  <SRC_COLUMN>myColumn</SRC_COLUMN>  
 </ROW>
</ROWSET>

而02_transformation.xsl文件是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fn="http://www.w3.org/2005/xpath-functions">

<xsl:output method="text" indent="no" encoding="UTF-8"/>

  <xsl:template match="/ROWSET">
    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
    &lt;!DOCTYPE POWERMART SYSTEM "powrmart.dtd"&gt;
  </xsl:template>
</xsl:stylesheet>

结果应该是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE POWERMART SYSTEM "powrmart.dtd">

但结果是

TEMPLATE_ERROR: TRANSFORMATION: ORA-31011: XML parsing failed
ORA-19213: error occurred in XML processing at lines 1
LPX-00209: PI names starting with XML are reserved

我搜索了许多帮助网站,但我什至不明白这是什么意思。 我不知道它是否重要,但这在 Apex 应用程序中运行,它从数据库中读取表名(从...中选择),从这个结果创建 XML,我正在解析这个结果。问题是,这段代码在资源管理器中工作,但在这个应用程序中没有。 任何人都可以帮助我吗? 非常感谢 J.

【问题讨论】:

  • 如果您的输出方法是text,为什么需要 XML 声明和/或 DOCTYPE 声明?无论如何,仅使用您的代码无法复制您声称的结果。
  • 错误的一个可能原因是 XML 声明之前的空格。这将被复制到结果文档中。 XML 解析器发现 "
  • 原因是生成的文本将以我选择的结尾保存到文件中。实际上,这将是一个文本,但使用 .xml 它将被读取并用作 xml 文件。
  • 空格不是这个错误的原因。我已经删除了所有空间,错误仍然存​​在。

标签: xml xslt transformation


【解决方案1】:

生成带有所示声明的文档的正确方法是:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="powrmart.dtd" />

<xsl:template match="/ROWSET">
    <POWERMART/>
</xsl:template>

</xsl:stylesheet>

【讨论】:

  • 是的,我知道,但是 Apex 中的内部应用程序对此有任何问题 :-( 这就是我使用文本的原因。
  • 您应该找出您的目标应用程序需要什么样的输出 - 然后询问如何产生这样的输出。不需要使用文字文本来模拟 XML/DOCTYPE 声明。
  • 我试过了,它成功了,但是出现了另一个问题,现在我确定我不能生成 XML,我必须将输出生成为 TEXT。问题是:&lt;xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="powrmart.dtd" /&gt; dtd 文件不在 apex 应用程序中,但我在这里需要它。是的,可以在生成此文件后添加另一个文件,但这不仅仅是一个文件,可以有更多的这个生成的文件。这就是我需要生成 TEXT 输出的原因。不过谢谢你的提示。
  • 恐怕我不明白你的意思。如果您不生成 XML,为什么需要 XML 声明 - 这是我在对您的问题的第一条评论中提出的问题。
【解决方案2】:

产生所需输出的一种方法——如果您真的必须将其输出为文本

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

  <xsl:template match="/*">
    <xsl:value-of select=
    "'&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#xA;'"/>
    <xsl:value-of select="'&lt;!DOCTYPE POWERMART SYSTEM &quot;powrmart.dtd&quot;&gt;'"/>
  </xsl:template>
</xsl:stylesheet>

应用于任何 XML 文档(忽略/未使用)时,结果为

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE POWERMART SYSTEM "powrmart.dtd">

请注意:但是,不需要 XSLT 将字符串文字写入输出 - 在 C(或任何传统 PL)应用程序中执行此操作。

通过正确使用&lt;xsl:output&gt; 声明,可以输出所需的两行作为XML 文档的序言。

只需使用

<xsl:output doctype-system="powrmart.dtd" />

你不需要指定methodversionencoding属性,因为这些伪属性生成的默认值XML 声明正是您所需要的。

【讨论】:

  • 谢谢!我试试看,你的建议可行。不幸的是我没有编写这个内部应用程序,所以我不知道什么可以在这里工作,什么不能。谢谢,J。
  • @MichaelKay 在对您的问题的评论中解释了这一点。您生成的文本稍后会(通过您调用的内容)解释为 XML。 XML 声明前面不能有空格。在你的情况下是。因此,XML Parser 无法识别该声明,并认为它是一个普通的处理指令 (PI)。但 XML 标准不建议元素、属性或 PI 名称以任何大写的字符串“xml”开头。所以错误。
  • 我尝试了您的解决方案,但它不起作用。我认为这个问题将在内部应用程序中。我将尝试找到另一个解决方案,而不使用此应用程序。 :-/ 但是非常感谢您的提示!
猜你喜欢
  • 2018-08-24
  • 2021-06-16
  • 2022-11-17
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
相关资源
最近更新 更多