【问题标题】:Oracle XML-Hierarchy with child nodes (NEWCONTEXTFROMHIERARCHY)带有子节点的 Oracle XML 层次结构 (NEWCONTEXTFROMHIERARCHY)
【发布时间】:2019-07-27 20:25:56
【问题描述】:

我的目标是像这样的XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<IMPORT>
  <PGR name="Product Group 1">
    <PGR name="Product Group 1-1">
      <PGR name="Product Group 1-1-1">
        <PRO name="Product X">
          <PRV name="Product Variant X-1" />
        </PRO>
      </PGR>
    </PGR>
  </PGR>
</IMPORT>

我的带有示例数据的表格:

create table PRODUCTS
(
  id             NUMBER(8) not null,
  name           VARCHAR2(100),
  baseproduct    VARCHAR2(100),
  productgroupid NUMBER(8)
);

insert into PRODUCTS (ID, NAME, BASEPRODUCT, PRODUCTGROUPID)
values (1, 'Product Variant 1', 'Product X', 3);

create table PRODUCTGROUPS
(
  id       NUMBER(8) not null,
  parentid NUMBER(8),
  name     VARCHAR2(100)
);

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (1, null, 'Product Group 1');

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (2, 1, 'Product Group 1-1');

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (3, 2, 'Product Group 1-1-1');

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (4, null, 'Product Group 2');

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (5, 4, 'Product Group 2-1');

insert into PRODUCTGROUPS (ID, PARENTID, NAME)
values (6, 5, 'Product Group 2-1-1');

每个PRODUCT(PRV-Node)都有一个BASEPRODUCT(PRO-Node)和一个PRODUCTGROUP(PGR-Node)。 PRODUCTGROUPS 是分层的。

到目前为止,我得到的是 XMLPRODUCTGROUP-Hierarchy 与:

select DBMS_XMLGEN.GETXMLTYPE(DBMS_XMLGEN.NEWCONTEXTFROMHIERARCHY('
select level, xmlelement("PGR", XMLATTRIBUTES(NAME)) 
from PRODUCTGROUPS
start with PARENTID is null
connect by nocycle PARENTID = PRIOR ID')) from dual

我也有所需的 XML 结构,但没有 PRODUCTGROUP-Hierarchy:

select P.ID,
  XMLROOT(
    XMLELEMENT("IMPORT",  
      XMLELEMENT("PGR", XMLATTRIBUTES(G.NAME as "name"),
        XMLELEMENT("PRO", XMLATTRIBUTES(P.BASEPRODUCT as "name"),
          XMLELEMENT("PRV", XMLATTRIBUTES(P.NAME as "name"))
        )   
      )        
    ) 
, version '1.0" encoding="utf-8') as XML
from PRODUCTS P join PRODUCTGROUPS G on P.PRODUCTGROUPID = G.ID

现在我不知道如何结合这两种方法来获得所需的XML-StructurePRODUCTGROUP-Hierarchy。有没有办法通过Oracle-XML-Functions 得到这个?

【问题讨论】:

    标签: xml oracle hierarchy


    【解决方案1】:

    说实话,我从未见过这个功能 (NEWCONTEXTFROMHIERARCHY),但这是我设法做到的。我创建了一个函数,它创建了层次树的所需部分,并联合了两个附加参数(基本产品和产品)。然后我使用了newcontextfromhierarchy。这种方式函数返回整个节点。

    create or replace function xml_hier(i_id in varchar2, i_base in varchar2, i_name in varchar2) return xmltype is
      v_ret xmltype;
    begin
      select dbms_xmlgen.getxmltype(dbms_xmlgen.newcontextfromhierarchy('
        with t as (
          select level lvl, xmlelement("PGR", XMLATTRIBUTES(NAME))
            from PRODUCTGROUPS
            where id in (select id 
                           from PRODUCTGROUPS
                           connect by prior PARENTID = ID start with id = '||i_id||')
            connect by PARENTID = prior ID
            start with parentid is null)
        select * from t 
        union all
        select (select max(lvl) + 1 from t), XMLELEMENT("PRO", XMLATTRIBUTES('''||i_base||''' as "name")) from dual
        union all
        select (select max(lvl) + 2 from t), XMLELEMENT("PRV", XMLATTRIBUTES('''||i_name||''' as "name")) from dual'))
      into v_ret
      from dual;
      return v_ret;
    end;
    

    因此,在创建了您的表之后,我运行:

    select p.id,
           xmlroot(
             xmlelement("IMPORT",  
               xml_hier(g.id, p.baseproduct, p.name))
             , version '1.0" encoding="utf-8') as xml
      from products p 
      join productgroups g on p.productgroupid = g.id;
    

    结果是:

    <?xml version="1.0" encoding="utf-8"?>
    <IMPORT>
      <PGR NAME="Product Group 1">
        <PGR NAME="Product Group 1-1">
          <PGR NAME="Product Group 1-1-1">
            <PRO name="Product X">
              <PRV name="Product Variant 1"/>
            </PRO>
          </PGR>
        </PGR>
      </PGR>
    </IMPORT>
    

    分层查询首先以相反的方向工作,以便找到祖先。然后它会正常运行,只使用已知的id

    我希望这会有所帮助:)

    【讨论】:

    • 非常感谢,这似乎完全符合我的需要!
    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多