【问题标题】:XMLTYPE ORA-31011: XML parsing failed without root element only nested elementsXMLTYPE ORA-31011: XML 解析失败,没有根元素,只有嵌套元素
【发布时间】:2018-02-07 10:23:54
【问题描述】:

我在 oracle 中有一个返回 XMLType 的函数,但没有根元素,因为根元素可以重复,我需要在另一个带有 XMLElements 的选择中使用它

我的简化功能是:

CREATE OR REPLACE FUNCTION F_XML_WITHOUT_ROOT 
RETURN XMLTYPE AS 

  vXML CLOB;
  vXML_TEMP CLOB;

BEGIN
  vXML := '';

  FOR cI IN (
    SELECT
      '10' ALM_IN_CODIGO,
      '1' LOC_IN_CODIGO,
      'DE' NAT_ST_CODIGO
    FROM DUAL
    UNION ALL
    SELECT
      '10' ALM_IN_CODIGO,
      '2' LOC_IN_CODIGO,
      'DE' NAT_ST_CODIGO
    FROM DUAL
  ) LOOP

    SELECT
      (
        XMLSerialize(content
          XMLElement("Item" 
            , XMLForest(
                cI.ALM_IN_CODIGO AS ALM
              , cI.LOC_IN_CODIGO AS LOC
              , cI.NAT_ST_CODIGO AS NAT
            ) Item
          ).extract('/*') indent
        ) 
      ) XML_BL_XML
      INTO vXML_TEMP
      FROM DUAL;

    vXML := vXML || vXML_TEMP;

  END LOOP;

  RETURN XMLTYPE.CreateXML(vXML);
END F_XML_WITHOUT_ROOT;

当我这样称呼时:

SELECT
MGCLI.F_XML_WITHOUT_ROOT()
FROM DUAL;

我收到错误代码

ORA-31011: XML parsing failed

我认为有更好的方法来完成这项工作,但我不确定如何

<Item><ALM>10</ALM><LOC>1</LOC><NAT>DE</NAT></Item>
<Item><ALM>10</ALM><LOC>2</LOC><NAT>DE</NAT></Item>

在这个选择中调用正确的函数来制作整个XML

 SELECT
 XMLSerialize(content
    XMLElement("Group", XMLAttributes('I' AS "OP")
    , XMLForest(
          3 FIL
        , 59 TPD
    ) 
    , XMLElement("Obs"
        , XMLForest(
          'N' OB_CH_TYPE
          , (
            'Ref. '
          ) OB_ST_OBS
        )
      )
      , (
        SELECT
          XMLAgg(
            XMLElement("Item", XMLAttributes('I' AS "OP")
              , XMLElement("ITN",1)
              , MGCLI.F_XML_WITHOUT_ROOT()
            )
          ) FROM DUAL
        )       
      ).extract('/*') indent
    ) XML_BL_XML
        FROM DUAL
        ;

【问题讨论】:

  • 好吧,你没有向我们展示 XML,所以谁知道呢。发布minimal reproducible example
  • @OldProgrammer 对不起,我的错,我只是编辑问题,但是如果你编译函数并拨打电话,它会弹出我遇到的错误......我做了代码自我解释
  • 我创建了一个返回类似 XML 的函数,并在另一个 XMLElement 中调用,如果需要,我可以放置其余代码
  • 我认为这可能不是我需要的函数......也许是返回结果以在XMLAgg中使用的过程@
  • 我在函数中使用了光标:create or replace FUNCTION F_XML_WITHOUT_ROOT RETURN SYS_REFCURSOR AS refC sys_refcursor; BEGIN OPEN refC FOR SELECT '10' ALM, '1' LOC, 'DE' NAT FROM DUAL UNION ALL SELECT '10' ALM, '2' LOC, 'DE' NAT FROM DUAL ; RETURN refC; END F_XML_WITHOUT_ROOT;

标签: xml oracle oracle11g xml-serialization xmltype


【解决方案1】:

XML 文档必须有一个根元素,否则它们的格式不正确,并且需要兼容的 XML 解析器将此类问题报告为错误。

通过将多个元素包装在单个根元素中来修复您的 XML。

【讨论】:

  • 我需要制作这样的 XML:&lt;Group&gt; &lt;FIL&gt;4&lt;/FIL&gt; &lt;Item OP="I"&gt; &lt;ITN&gt;1&lt;/ITN&gt; &lt;Item&gt; &lt;ALM&gt;10&lt;/ALM&gt; &lt;LOC&gt;1&lt;/LOC&gt; &lt;NAT&gt;DE&lt;/NAT&gt; &lt;/Item&gt; &lt;Item&gt; &lt;ALM&gt;10&lt;/ALM&gt; &lt;LOC&gt;2&lt;/LOC&gt; &lt;NAT&gt;DE&lt;/NAT&gt; &lt;/Item&gt; &lt;/Group&gt;
  • 您在该评论中发布的 XML 格式也不正确。
  • 为什么?是我必须与系统集成吗
  • 未关闭的Item 元素。
  • 哦,那是因为我一个接一个地写,忘记关闭一个,我用返回所有的代码更新了
【解决方案2】:

我有一种方法来制作我想要的东西:

我改变功能:

create or replace FUNCTION F_XML_WITHOUT_ROOT 
RETURN sys_refcursor AS 

  refC sys_refcursor;
BEGIN

  OPEN refC FOR
    SELECT
      '10' ALM,
      '1' LOC,
      'DE' NAT
    FROM DUAL
    UNION ALL
    SELECT
      '10' ALM,
      '2' LOC,
      'DE' NAT
    FROM DUAL
  ;

  RETURN refC;
END F_XML_WITHOUT_ROOT;

然后我更改主要的SELECT 以制作整个 XML:

选择 XMLSerialize(内容

    XMLElement("Group", XMLAttributes('I' AS "OP")
    , XMLForest(
          3 FIL
        , 59 TPD
    ) 
    , XMLElement("Obs"
        , XMLForest(
          'N' OB_CH_TYPE
          , (
            'Ref. '
          ) OB_ST_OBS
        )
      )

      , (
        SELECT
          XMLAgg(
            XMLElement("Item", XMLAttributes('I' AS "OP")
              , XMLElement("ITN",1)
              , 
              (SELECT
                XMLAgg(
                  XMLElement("Item", 
                     XMLElement("ALM", ALM) 
                    ,XMLElement("LOC", LOC)
                    ,XMLElement("NAT", NAT)
                  )
                ) 
                FROM 
                XMLTABLE(
                  '/ROWSET/ROW'
                  PASSING XMLType(MGCLI.F_XML_WITHOUT_ROOT())
                  COLUMNS
                  ALM  PATH 'ALM',
                  LOC PATH 'LOC',
                  NAT PATH  'NAT'
                )
              ) 
            )
          ) FROM DUAL
        )

      ).extract('/*') indent
    ) XML_BL_XML
        FROM DUAL;

结果:

<Group OP="I">
  <FIL>3</FIL>
  <TPD>59</TPD>
  <Obs>
    <OB_CH_TYPE>N</OB_CH_TYPE>
    <OB_ST_OBS>Ref. </OB_ST_OBS>
  </Obs>
  <Item OP="I">
    <ITN>1</ITN>
    <Item>
      <ALM>10</ALM>
      <LOC>1</LOC>
      <NAT>DE</NAT>
    </Item>
    <Item>
      <ALM>10</ALM>
      <LOC>2</LOC>
      <NAT>DE</NAT>
    </Item>
  </Item>
</Group>

这是我找到的最好的方法,也许还有其他方法......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-17
    • 2011-10-02
    • 2017-03-22
    • 1970-01-01
    • 2019-06-22
    • 2019-10-13
    • 1970-01-01
    • 2021-07-08
    相关资源
    最近更新 更多