Oracle XML Schema验证日期模式错误

时间:2016-05-26 23:04:30

标签: xml oracle xsd

我正在尝试使用XSD验证XML。但它引发了关于日期格式的奇怪错误:

  

[1]:LSX-00333:文字“2016-05-26T16:37:42.000000”对于模式无效

然而,这就是我在XML中所拥有的:

<?xml version="1.0" encoding="UTF-8"?>
<root DataFeed="2016-04" 
      VersionXSD="2.0" 
      Currency="USD" 
      DataProcessDate="2016-05-26T16:37:42" 
      xmlns="http://www.millicom.com">

我在XSD中有这个:

<xs:attribute name="DataProcessDate" 
              use="required" 
              type="DateTimeType"/>

<xs:simpleType name="DateTimeType">
    <xs:restriction base="xs:dateTime">
        <xs:pattern value=".+(\-10:00|\-09:00|\-08:00|\-07:00|\-06:00|\-05:00|\-04:00|\+00:00|Z|-04:00)"/>
    </xs:restriction>
</xs:simpleType>

这是我的代码:

DECLARE
   v_schema_url   VARCHAR2 (200) := 'MyFact.xsd';
   v_blob         BLOB;
   v_clob         CLOB;
   v_xml          XMLTYPE;
   xml_file BFILE;
   xmlClob CLOB;

   src_offset number := 1 ;
   dest_offset number := 1 ;
   lang_ctx number := DBMS_LOB.DEFAULT_LANG_CTX;
   warning integer;
   res integer;
BEGIN
   dbms_xmlschema.deleteschema(v_schema_url); 
   DBMS_XMLSCHEMA.registerschema (schemaurl   => v_schema_url,
                                  schemadoc   => bfilename ('DIR_XSD','MyFact.xsd'),
                                  local       => TRUE);
   xml_file := BFILENAME('DIR_XSD', 'Test.xml');
   DBMS_LOB.CREATETEMPORARY(xmlClob, true);
   DBMS_LOB.FILEOPEN(xml_file, DBMS_LOB.FILE_READONLY);
   DBMS_LOB.LOADCLOBFROMFILE(xmlClob, xml_file, DBMS_LOB.LOBMAXSIZE, src_offset,
                             dest_offset, DBMS_LOB.DEFAULT_CSID, lang_ctx, warning);

   v_xml := XMLType.createXML(xmldata=>xmlClob,schema=>v_schema_url);

   DBMS_LOB.FILECLOSEALL();
   DBMS_LOB.FREETEMPORARY(xmlClob);

   v_xml.schemaValidate();

   IF v_xml.isschemavalid (v_schema_url) = 1 THEN
      DBMS_OUTPUT.put_line ('valid');
   ELSE
      DBMS_OUTPUT.put_line ('not valid');
   END IF;
END;

由于某种原因,它增加了微秒,并且未通过模式检查。我怎么能避免这个? 我希望的行为是正确执行,输出为“valid”

2 个答案:

答案 0 :(得分:1)

你可能会做这样的事情。 我假设你的数据类型是这样声明的。

  <xs:simpleType name="DataProcessDateType">
    <xs:restriction base="xs:dateTime">
       <xs:pattern value="\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}"/>
    </xs:restriction>
  </xs:simpleType>

这里发生了什么。

  • 1)2016-05-26T16:37:42字符串转换为xs:dataTime并且看起来像 2016-05-26T16:37:42.000000

  • 2)接下来xsd将匹配2016-05-26T16:37:42.000000转移到模式"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}",但模式没有尾随零。并且引发了LSX-00333错误。

你能做什么。

  • (1-选项)在模式"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}"
  • 中包含尾随零
  • (2 - option)从类型中删除xs:pattern;

     xsd clob := q'~<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"   xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="root">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute type="xs:string" name="DataFeed"/>
              <xs:attribute type="xs:float" name="VersionXSD"/>
              <xs:attribute type="xs:string" name="Currency"/>
              <xs:attribute type="DataProcessDateType" name="DataProcessDate"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      <xs:simpleType name="DataProcessDateType">
        <xs:restriction base="xs:dateTime">
           <xs:pattern value="\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}"/>
        </xs:restriction>
       </xs:simpleType>
    </xs:schema>~';
    begin 
       DBMS_XMLSCHEMA.registerschema (schemaurl   => 'test_xsd',
                                      schemadoc   => xmltype(xsd),
                                      local       => TRUE);
    end;
    

    - exec dbms_XMLSCHEMA.deleteSchema(schemaurl =&gt;'test_xsd');     宣布         vxml xmltype:= xmltype(q'~~');

    begin 
      vxml := vxml.createschemabasedxml('test_xsd');
      vxml.schemaValidate();
     IF vxml.isschemavalid ('test_xsd') = 1 THEN
          DBMS_OUTPUT.put_line ('valid');
       ELSE
          DBMS_OUTPUT.put_line ('not valid');
       END IF;
    end;
    

答案 1 :(得分:1)

虽然您没有向我们展示您的数据类型定义,但我的第一直觉是Oracle正在不正确地解释规范。我个人认为使用具有非字符串数据类型的模式是非常值得怀疑的,但是规范非常清楚(第2部分,第4.1.4节,验证规则数据类型有效),模式构面应该用于匹配在源文档(在空白规范化之后)称为“词法空间中的文字”,然后将其转换为值空间,其中评估其他方面,如minInclusive和枚举。我得到的印象是,Oracle已经采用了词法值,将其转换为值空间,然后针对模式测试值的规范词法形式。但这也不对,因为规范的词法形式在小数秒部分不能包含尾随零(见3.2.7.2)。