【问题标题】:Build an XML with XMLELEMENT - ORACLE SQL 11g query使用 XMLELEMENT 构建 XML - ORACLE SQL 11g 查询
【发布时间】:2015-12-02 03:30:58
【问题描述】:

我正在尝试使用 SQL 查询 (Oracle) 创建以下 XML:

 <Changes>
   <Description>Some static test</Description>
   <Notes>Some static test</Notes>

   <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #1</User>
      <BusinessSource>VALUE from Table #1</BusinessSource>
      <ApplicationRole>VALUE from Table #1</ApplicationRole>
   </UserChange>
    <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #2</User>
      <BusinessSource>VALUE from Table #2</BusinessSource>
      <ApplicationRole>VALUE from Table #2</ApplicationRole>
   </UserChange>
    <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #3</User>
      <BusinessSource>VALUE from Table #3</BusinessSource>
      <ApplicationRole>VALUE from Table #3</ApplicationRole>
   </UserChange>   
</Changes>

我正在使用的表格如下所示:

ID    USER     SOURCE   ROLE
1     test1    src1     role1
2     test1    src1     role1
3     test1    src1     role2
4     user2    src      role
5     user3    src      role
6     user1    src      role

我想编写一个查询,该查询将根据表中的值创建一个动态 XML。 例如: 查询只应采用 user='test1' 的值,输出将是以下 XML:

<Changes>
   <Description>Some static test</Description>
   <Notes>Some static test</Notes>

   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role1</ApplicationRole>
   </UserChange>
   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role1</ApplicationRole>
   </UserChange>
   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role2</ApplicationRole>
   </UserChange>   
</Changes>

我已经开始写查询了:

SELECT XMLElement("Changes", 
              XMLElement("Description", 'sometext'),
              XMLElement("Notes", 'sometext'),
              XMLElement("FulfillmentDate", 'Some Date'),

                  XMLElement("UserChange",
                  XMLElement("Operation", 'sometext'),
                  XMLElement("User", 'sometext'),
                  XMLElement("BusinessSource", 'sometext'),
                  XMLElement("ApplicationRole", 'sometext')                      

                  )).GETSTRINGVAL() RESULTs
               FROM DUAL;

我需要迭代其他值并使它们成为完整 XML 的一部分。

感谢您的帮助。

谢谢

【问题讨论】:

  • 您使用或拥有哪些语言:C#、Java、PHP、Python、R、SAS、MS Excel/Access VBA?作为一种特殊用途的语言,SQL 受到限制并且因方言而异。但是所有这些都可以与其他人一起获取查询结果、循环记录和生成 XML 文档,甚至可以使用 XSLT 进行样式化。

标签: sql xml oracle oracle11g


【解决方案1】:

你可以使用这个查询:

select xmlelement("Changes",
           xmlforest(
               'Some Static Text' "Description"
             , 'Some Static Text' "Notes")
         , xmlagg(
             xmlelement("UserChange",
               xmlforest('Static Text' "Operation",
                         "USER" "User",
                         SOURCE "BusinessSource",
                         ROLE "ApplicationRole")
             )
           )
       ),getclobval()
  from table
 where "USER" = 'test1';

但请记住,XMLAGG 函数是一个聚合函数。在这种情况下,表中的每个选定列都包含在聚合中,因此不需要分组依据。但是,如果您想在 XMLAGG 之外包含表中的某些列,则需要将它们包含在 group by 语句中。此外,由于USER 是保留字,因此需要用双引号括起来才能用作列引用。

【讨论】:

    【解决方案2】:

    对于未来的读者,这里是以 OP 的数据需求为例,将 SQL 查询转换为 XML 文档的开源编程解决方案。

    以下代码示例不限于任何数据库 SQL 方言(即,可使用以下相应连接模块转移到其他 RDBMS 是 Oracle 特定的)。

    对于 Python(使用 cx_Oracle 和 lxml 模块):

    import os
    import cx_Oracle
    import lxml.etree as ET
    
    # Set current directory
    cd = os.path.dirname(os.path.abspath(__file__))
    
    # DB CONNECTION AND QUERY
    db = cx_Oracle.connect("uid/pwd@database")    
    cur = db.cursor()
    cur.execute("SELECT * FROM OracleData where user='test1'")
    
    # WRITING XML FILE
    root = ET.Element('Changes')
    DescNode = ET.SubElement(root, "Description").text = 'Some static test'    
    NotesNode = ET.SubElement(root, "Notes").text = 'Some static test'  
    
    # LOOPING THROUGH QUERY RESULTS TO WRITE CHILD ELEMENTS 
    for row in cur.fetchall():
        UCNode = ET.SubElement(root, "UserChange")
        ET.SubElement(UCNode, "Operation").text = 'Static Text'    
        ET.SubElement(UCNode, "User").text = row[1]
        ET.SubElement(UCNode, "BusinessSource").text = row[2]    
        ET.SubElement(UCNode, "ApplicationRole").text = row[3]   
    
    # CLOSE CURSOR AND DATABASE
    cur.close()
    db.close()
    
    tree_out = (ET.tostring(root, pretty_print=True, xml_declaration=True, encoding="UTF-8"))
    
    xmlfile = open(os.path.join(cd, 'OracleXML.xml'),'wb')
    xmlfile.write(tree_out)
    xmlfile.close()
    

    对于 PHP(使用 PDO Oracle OCI 和 DOMDocument)

    // Set current directory
    $cd = dirname(__FILE__);
    
    // create a dom document with encoding utf8 
    $domtree = new DOMDocument('1.0', 'UTF-8');
    $domtree->formatOutput = true;
    $domtree->preserveWhiteSpace = false;
    
    // Opening db connection
    $db_username = "your_username";
    $db_password = "your_password";
    $db = "oci:dbname=your_sid";
    
    try {
        $dbh = new PDO($db,$db_username,$db_password);          
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        $sql = "SELECT * FROM OracleData where user='test1'";    
        $STH = $dbh->query($sql);    
        $STH->setFetchMode(PDO::FETCH_ASSOC); 
    }
    
    catch(PDOException $e) {  
        echo $e->getMessage();
        exit;
    }
    
    /* create the root element of the xml tree */
    $xmlRoot = $domtree->createElement("Changes");
    $xmlRoot = $domtree->appendChild($xmlRoot);
    
    $DescNode = $xmlRoot->appendChild($domtree->createElement('Description',  'Some static test'));
    $NotesNode = $xmlRoot->appendChild($domtree->createElement('Notes',  'Some static test'));
    
    /* loop query results through child elements */
    while($row = $STH->fetch()) {  
    
        $UCNode = $xmlRoot->appendChild($domtree->createElement('UserChange'));
    
        $operationNode = $UCNode->appendChild($domtree->createElement('Operation', 'Some static text'));
        $userNode = $UCNode->appendChild($domtree->createElement('User', $row['USER']));
        $sourceNode = $UCNode->appendChild( $domtree->createElement('BusienssSource', $row['SOURCE']));
        $roleNode = $UCNode->appendChild($domtree->createElement('ApplicationRole', $row['ROLE']));
    
    }
    
    file_put_contents($cd. "/OracleXML.xml", $domtree->saveXML());
    
    # Closing db connection
    $dbh = null;
    exit;
    

    对于 R(使用 ROracle 和 XML 包):

    library(XML)
    library(ROracle)
    
    # SET CURRENT DIRECTORY   
    setwd("C:\\Path\\To\\R\\Script")
    
    # OPEN DATABASE AND QUERY
    conn <-dbConnect(drv, username = "", password = "", dbname = "")
    df <- dbGetQuery(conn, "select * from OracleData where user= 'test1';")
    dbDisconnect(conn)
    
    # CREATE XML FILE
    doc = newXMLDoc()
    root = newXMLNode("Changes", doc = doc)
    descNode = newXMLNode("Description", "Some static test", parent = root)
    notesNode = newXMLNode("Notes", "Some static test", parent = root)
    
    # WRITE XML NODES AND DATA
    for (i in 1:nrow(df)){
      UCNode = newXMLNode("UserChange", parent = root)
    
      operationNode = newXMLNode("Operation", "Some static text", parent = UCNode)
      userNode = newXMLNode("User", df$USER[i], parent = UCNode)
      sourceNode = newXMLNode("BusinessSource", df$SOURCE[i], parent = UCNode)
      roleNode = newXMLNode("ApplicationRole", df$ROLE[i], parent = UCNode)
    }
    
    # OUTPUT XML CONTENT TO FILE
    saveXML(doc, file="OracleXML.xml")
    

    【讨论】:

      【解决方案3】:

      我找到了解决办法:

      select XMLElement("Changes", 
                    XMLElement("Description", 'sometext'),
                    XMLElement("Notes", 'sometext'),
                    XMLElement("FulfillmentDate", 'Some Date'),
                        XMLAgg(XML_CANDIDATE) ).GETSTRINGVAL() RESULTS
      
      from 
      (
      
      select XMLAGG(
              XMLElement("UserChange",
              XMLElement("Operation", 'sometext'),
              XMLElement("User", 'sometext'),
              XMLElement("BusinessSource", 'sometext'),
              XMLElement("ApplicationRole", 'sometext')))  XML_CANDIDATE
      from
      table);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 2017-10-09
        • 1970-01-01
        • 2015-10-04
        • 2021-10-26
        • 2011-11-01
        相关资源
        最近更新 更多