在XSLT中查询数据库并将结果应用于输出XML

时间:2015-12-07 09:37:13

标签: xml xslt saxon

我需要根据ProductItemId查询数据库,并获取以下XML的ProductName,ProductItemCode,ProductType和ActCode。我正在使用SaxonEE进行转换。查询应该在XSLT内部触发

我的输入XML是:

<?xml version="1.0" encoding="UTF-8"?>
<ListOfSublines>
   <OrderSubline>
      <OrderSublineNumber>1</OrderSublineNumber>
      <OrderSublineType>ADD</OrderSublineType>
      <OrderlineInstance>120</OrderlineInstance>
      <Lob/>
      <Circle/>
      <Zone/>
      <ProductItem>
         <ProductItemId>10</ProductItemId>
         <AdditionalParams>
            <Parameter name="LOC_CODE" value="25"/>
            <Parameter name="LOC_DESC" value="Kolkata Circle"/>
         </AdditionalParams>
      </ProductItem>
   </OrderSubline>
   <OrderSubline>
      <OrderSublineNumber>2</OrderSublineNumber>
      <OrderSublineType>ADD</OrderSublineType>
      <OrderlineInstance>121</OrderlineInstance>
      <Lob/>
      <Circle/>
      <Zone/>
      <ProductItem>
         <ProductItemId>11</ProductItemId>
         <AdditionalParams>
            <Parameter name="PRODUCT_INDICATOR" value="Mobility Voice"/>
            <Parameter name="RATE CLASS" value="1"/>
            <Parameter name="RRCC" value="Bharti Tele-Ventures"/>
         </AdditionalParams>
      </ProductItem>
   </OrderSubline>
   <OrderSubline>
      <OrderSublineNumber>3</OrderSublineNumber>
      <OrderSublineType>ADD</OrderSublineType>
      <OrderlineInstance>122</OrderlineInstance>
      <Lob/>
      <Circle/>
      <Zone/>
      <ProductItem>
         <ProductItemId>12</ProductItemId>
         <AdditionalParams/>
      </ProductItem>
   </OrderSubline>

</ListOfSublines>

预期产出:

<?xml version="1.0" encoding="UTF-8"?>
    <ListOfSublines>
       <OrderSubline>
          <OrderSublineNumber>1</OrderSublineNumber>
          <OrderSublineType>ADD</OrderSublineType>
          <OrderlineInstance>120</OrderlineInstance>
          <Lob/>
          <Circle/>
          <Zone/>
          <ProductItem>
             <ProductItemId>10</ProductItemId>
             <ProductName>Value from Oracle Db based on ProductItemId 10</ProductName>
             <ProductItemCode>Value from Oracle Db</ProductItemCode>
             <ProductType>Value from Oracle Db</ProductType>
             <ActCode>Value from Oracle Db</ActCode>
             <AdditionalParams>
                <Parameter name="LOC_CODE" value="25"/>
                <Parameter name="LOC_DESC" value="Kolkata Circle"/>
             </AdditionalParams>
          </ProductItem>
       </OrderSubline>
       <OrderSubline>
          <OrderSublineNumber>2</OrderSublineNumber>
          <OrderSublineType>ADD</OrderSublineType>
          <OrderlineInstance>121</OrderlineInstance>
          <Lob/>
          <Circle/>
          <Zone/>
          <ProductItem>
             <ProductItemId>11</ProductItemId>
             <ProductName>Value from Oracle Db based on ProductItemId 11</ProductName>
             <ProductItemCode>Value from Oracle Db</ProductItemCode>
             <ProductType>Value from Oracle Db</ProductType>
             <ActCode>Value from Oracle Db</ActCode>
             <AdditionalParams>
                <Parameter name="PRODUCT_INDICATOR" value="Mobility Voice"/>
                <Parameter name="RATE CLASS" value="1"/>
                <Parameter name="RRCC" value="Bharti Tele-Ventures"/>
             </AdditionalParams>
          </ProductItem>
       </OrderSubline>
       <OrderSubline>
          <OrderSublineNumber>3</OrderSublineNumber>
          <OrderSublineType>ADD</OrderSublineType>
          <OrderlineInstance>122</OrderlineInstance>
          <Lob/>
          <Circle/>
          <Zone/>
          <ProductItem>
             <ProductItemId>12</ProductItemId>
             <ProductName>Value from Oracle Db based on ProductItemId 12</ProductName>
             <ProductItemCode>Value from Oracle Db</ProductItemCode>
             <ProductType>Value from Oracle Db</ProductType>
             <ActCode>Value from Oracle Db</ActCode>
             <AdditionalParams/>
          </ProductItem>
       </OrderSubline>

    </ListOfSublines>

3 个答案:

答案 0 :(得分:0)

您可以使用Saxon的SQL扩展(它可以完成80%的人需要的20%,但绝不完整),或者您可以使用Java扩展性机制编写自己的扩展。

答案 1 :(得分:0)

SQL和XSLT都是专用语言(共享声明类型的特征),意味着要做一件特别的事情。对于通常意味着数据库操作或检索或DDL and DML过程的SQL,以及对于XSLT而言意味着操作XML文档的SQL。

考虑使用通用语言,如Java(Oracle产品),C#,Python,PHP,Perl,VB甚至R和SAS以及其他语言来处理Oracle数据库检索需求和XML文档解析和操作。此外,这些上述语言和其他语言为XSLT 1.0处理器维护自己的库,包括XPath 1.0和XML DOM文档库。更重要的是,这些语言可以通过命令行(线程或子进程)调用外部可执行文件(如Saxon EE)来传递所需的参数,例如xml或xslt文档路径。最后,这些相同的语言维护SQL ODBC / OLEDB api库,包括Oracle数据库。顺便说一下,Oracle(与其他企业级RDMS -SQL Server,PostgreSQL一样)在其PL / SQL方言中维护自己的XML manipulation syntax and features

总而言之,根据您的需求,请考虑以下步骤:

  1. 选择熟悉的通用语言(上述或其他);
  2. 安装必需的Oracle数据库连接器API(即Java JDBC driver, Python的cx_Oracle,PHP&#39} PDO DSN);
  3. 使用SQL查询选择数据的数据库;
  4. 遍历查询数据以动态创建输入XML文档;
  5. 使用通用编码或外部可执行文件运行XSLT以获得最终的XML输出;

答案 2 :(得分:0)

感谢@Michael的提示,我尝试了SAXON SQL扩展,并且能够查询数据库。

这是适用于我的XSLT代码:

    <xsl:transform version="2.0"
      exclude-result-prefixes="java saxon xsd xsi xsl"
      extension-element-prefixes="saxon sql"

      xmlns:java="http://saxon.sf.net/java-type"
      xmlns:saxon="http://saxon.sf.net/"
      xmlns:sql="java://net.sf.saxon.sql.SQLElementFactory"

      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    >
<xsl:variable name="count" select="0" saxon:assignable="yes"/>
      <xsl:output method="xml" indent="yes"/>
      <xsl:preserve-space elements="*" />

      <xsl:param name="jdbc.driver"   as="xsd:string" select="'com.mysql.jdbc.Driver'" />

      <xsl:param name="jdbc.database" as="xsd:string" select="'jdbc:mysql://localhost:3306/test'" />

      <xsl:param name="jdbc.user" as="xsd:string" select="'root'" />
      <xsl:param name="jdbc.pass" as="xsd:string" select="'root'" />
      <xsl:template match="BOOKS">

            <xsl:variable name="sql.conn" as="java:java.sql.Connection">
              <sql:connect driver="{$jdbc.driver}" database="{$jdbc.database}" user="{$jdbc.user}" password="{$jdbc.pass}">
                <xsl:fallback>
                  <xsl:message terminate="yes">SQL extenstions are not installed</xsl:message>
                </xsl:fallback>
              </sql:connect>
            </xsl:variable>

    <xsl:for-each select="ITEM">
        <sql:insert connection="$sql.conn" table="book">
            <sql:column name="title" select="TITLE"/>
            <sql:column name="author" select="AUTHOR"/>
            <sql:column name="category" select="@CAT"/>
        </sql:insert>
        <saxon:assign name="count" select="$count+1"/> 
    </xsl:for-each>
<xsl:variable name="book-table">
    <sql:query connection="$sql.conn" table="book" column="*" row-tag="book" column-tag="col"/>
    </xsl:variable>

    <xsl:message>There are now <xsl:value-of select="count($book-table//book)"/> books.</xsl:message>
    <new-book-table>
        <xsl:copy-of select="$book-table"/>
    </new-book-table>

      </xsl:template>

    </xsl:transform>

希望对别人有所帮助。