【问题标题】:Why DBMS_XMLSCHEMA fails to validate a valid xs:dateTime?为什么 DBMS_XMLSCHEMA 无法验证有效的 xs:dateTime?
【发布时间】:2016-11-22 21:59:51
【问题描述】:

我将验证和处理第三方提供的 XML。 XML 符合同样由第三方提供的标准化 XML 模式。

为了验证,我基本上以这种方式使用 DBMS_XMLSCHEMA:

-- pseudocode follows
declare
  xmldoc xmltype;
begin
  dbms_xmlschema.registerschema(schemaurl => name,
                                schemadoc => xmltype(schema),
                                local => true,
                                gentypes => false,
                                gentables => false
                                );
  xmldoc := xmltype(xml).createSchemaBasedXML(schema_name);
  xmldoc.schemavalidate;
end;

验证似乎有效,只是我遇到了 XML 模式类型 xs:dateTime 的问题,如下所示。

使用 XML 架构:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="datetime-issue">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="time" type="xs:dateTime" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

以下 XML 的验证:

<?xml version="1.0" encoding="UTF-8"?>
<datetime-issue>
  <time>2011-06-15T16:58:23</time>
  <!-- Oracle doesn't like timezone ? -->
  <time>2011-06-15T16:58:23+02:00</time>
  <time>2011-06-16T09:55:01</time>
</datetime-issue>

在第二个时间元素上意外失败:

ORA-30992: error occurred at Xpath /datetime-issue/time[2]
ORA-01830: date format picture ends before converting entire input string
ORA-06512: at "SYS.XMLTYPE", line 354

AFAICS 2011-06-15T16:58:23+02:00 应该是一个有效的 XML 模式 xs:dateTime 值,并且 DBMS_XMLSCHEMA 根本不应该抱怨这一点。验证也应该独立于任何数据库日期格式设置,对吧?

那么这是 Oracle 的怪癖吗?如果是,解决方法是什么?或者我应该以不同的方式配置 Oracle 和/或 DBMS_XMLSCHEMA 吗?还是我误解了什么或......

我正在运行 Oracle Database 11g 版本 11.2.0.1.0。

如果有任何价值,上面的示例 XML 架构和数据可以通过使用 Xerces 的 exchangerxml 正确验证。

【问题讨论】:

    标签: oracle validation datetime xsd oracle11g


    【解决方案1】:

    我认为您可以通过添加以下内容来解决此问题:

    xdb:SQLType="TIMESTAMP WITH TIME ZONE"
    

    到 XML 模式中的元素。虽然这可能会在非时区记录上出错...

    【讨论】:

    【解决方案2】:

    这只是回答我的问题的相关 Oracle 文档的集合。我接受了 Phil 的回答,因为我在此基础上找到了正确的文档部分。

    来自Oracle XML DB Developer's Guide 11g Release 2 (11.2)的章节7 XML Schema Storage and Query: Basic

    使用时区

    以下 XML Schema 数据类型允许将可选的时区指示符作为其文字值的一部分。

    • xsd:dateTime
    • xsd:time
    • xsd:date
    • xsd:gYear
    • xsd:gMonth
    • xsd:gDay
    • xsd:gYearMonth
    • xsd:gMonthDay

    默认情况下,XML 架构注册将 xsd:dateTimexsd:time 映射到 SQL 数据类型 TIMESTAMP,并将所有其他数据类型映射到 SQL 数据类型 DATE。 SQL 数据类型 TIMESTAMPDATE 不允许使用时区指示符。

    如果您的应用程序需要使用时区指示器,则使用属性SQLType 将SQL 数据类型指定为TIMESTAMP WITH TIME ZONE。这确保可以正确存储和检索包含时区指示符的值。例如:

    <element name="dob" type="xsd:dateTime"
          xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
    <attribute name="endofquarter" type="xsd:gMonthDay"
           xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
    

    使用尾随 Z 表示 UTC 时区

    XML Schema 允许将时区组件指定为 Z,以指示 UTC 时区。当带有结尾Z 的值存储在SQL TIMESTAMP WITH TIME ZONE 列中时,时区实际上存储为+00:00。因此,检索到的值包含结尾的+00:00,而不是原始的Z。例如,如果输入 XML 文档中的值为1973-02-12T13:44:32Z,则输出为1973-02-12T13:44:32.000000+00:00

    另见:

    【讨论】:

      猜你喜欢
      • 2011-02-18
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 2012-03-01
      • 2018-08-06
      • 2018-03-02
      相关资源
      最近更新 更多