使用XSLT样式表Oracle将xml转换为json

时间:2016-01-09 11:40:24

标签: json oracle xslt

在SQL开发人员中将XML数据转换为JSON时,我正在遵循JSON格式。

JSON:

  {"list":{"obj":{"att":{"val":"ABC"}}}}

但我希望JSON的格式如下

{"list":{"obj":{"att":{"id":"FirstName", "val":"ABC"}}}}

以下是我创建的用于将xml转换为JSON格式的oracle函数。

create or replace FUNCTION get_json(name IN VARCHAR2 ) RETURN clob IS
l_xml        xmltype;
v_XML_data clob;
l_json       xmltype;
l_json_result       clob;

begin 
v_XML_data := '<list><obj class="Plan"><att id="FirstName"> 
<val>ABC</val></att> </obj></list>';
IF(v_XML_data is not null) then
l_xml := xmltype.createxml(v_XML_data);
dbms_output.put_line(l_xml.getclobVal());
-- convert the JSON
l_json :=     
l_xml.transform(xmltype(roelvt.json_util_pkg.get_xml_to_json_stylesheet));
-- dbms_output.put_line(l_json);
l_json_result :=l_json.getclobVal();
-- Display the JSON  
dbms_output.put_line(l_json.getclobVal());
RETURN  l_json_result;
else
RETURN  null;
end if;
exception
when others then 
null;
RETURN  null;
END;

以下是XSLT样式表:

<?xml version="1.0" encoding="UTF-8"?>     <xsl:stylesheetversion="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:output indent="no" omit-xml-declaration="yes"
method="text"   encoding="UTF-8" media-type="text/x-json"/>
<xsl:strip-space elements="*"/>
<!--contant-->
<xsl:variable name="d">0123456789</xsl:variable>

<!-- ignore document text -->
<xsl:template match="text()[preceding-sibling::node()
or following-  sibling::node()]"/>

  <!-- string -->
  <xsl:template match="text()">
  <xsl:call-template name="escape-string">
  <xsl:with-param name="s" select="."/>
  </xsl:call-template>
  </xsl:template>


  <xsl:template name="escape-string">
   <xsl:param name="s"/>
  <xsl:text>"</xsl:text>
  <xsl:call-template name="escape-bs-string">
  <xsl:with-param name="s" select="$s"/>
  </xsl:call-template>
  <xsl:text>"</xsl:text>
  </xsl:template>

  <!-- Escape the backslash (\) before everything else. -->
 <xsl:template name="escape-bs-string">
 <xsl:param name="s"/>
 <xsl:choose>
  <xsl:when test="contains($s,''\'')">
    <xsl:call-template name="escape-quot-string">
      <xsl:with-param name="s" select="concat(substring-  
    before($s,''\''),''\\'')"/>
    </xsl:call-template>
    <xsl:call-template name="escape-bs-string">
      <xsl:with-param name="s" select="substring-after($s,''\'')"/>
    </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
    <xsl:call-template name="escape-quot-string">
      <xsl:with-param name="s" select="$s"/>
    </xsl:call-template>
  </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <!-- Escape the double quote ("). -->
<xsl:template name="escape-quot-string">
<xsl:param name="s"/>
<xsl:choose>
  <xsl:when test="contains($s,'';'')">
    <xsl:call-template name="encode-string">
      <xsl:with-param name="s" select="concat(substring- 
 before($s,'';''),''&quot;'')"/>
    </xsl:call-template>
    <xsl:call-template name="escape-quot-string">
      <xsl:with-param name="s" select="substring-after($s,'';'')"/>
    </xsl:call-template>
  </xsl:when>
   <xsl:otherwise>
    <xsl:call-template name="encode-string">
      <xsl:with-param name="s" select="$s"/>
    </xsl:call-template>
  </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

  <!-- Replace tab, line feed and/or carriage return by its matching escape
  code. Can''t escape backslash
   or double quote here, because they don''t replace characters (; becomes  
\t), but they prefix
    characters (\ becomes \\). Besides, backslash should be seperate anyway, 
 because it should be
   processed first. This function can''t do that. -->
  <xsl:template name="encode-string">
   <xsl:param name="s"/>
 <xsl:choose>
  <!-- tab -->
   <xsl:when test="contains($s,'';'')">
    <xsl:call-template name="encode-string">
      <xsl:with-param name="s" select="concat(substring-
     before($s,'';''),''\t'',substring-after($s,'';''))"/>
    </xsl:call-template>
  </xsl:when>
  <!-- line feed -->
  <xsl:when test="contains($s,'';'')">
    <xsl:call-template name="encode-string">
      <xsl:with-param name="s" select="concat(substring-
    before($s,'';''),''\n'',substring-after($s,'';''))"/>
    </xsl:call-template>
  </xsl:when>

  <!-- carriage return -->
  <xsl:when test="contains($s,'';'')">
    <xsl:call-template name="encode-string">
      <xsl:with-param name="s" select="concat(substring-
     before($s,'';''),''\r'',substring-after($s,'';''))"/>
    </xsl:call-template>
  </xsl:when>
  <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <!-- number (no support for javascript mantise) -->
 <xsl:template match="text()[not(string(number())=''NaN'')]">
 <xsl:value-of select="."/>
 </xsl:template>

   <!-- boolean, case-insensitive -->
 <xsl:template match="text()   
[translate(.,''TRUE'',''true'')=''true'']">true</xsl:template>
 <xsl:template match="text()  
  [translate(.,''FALSE'',''false'')=''false'']">false</xsl:template>

 <!-- item:null -->
  <xsl:template match="*[count(child::node())=0]">
<xsl:call-template name="escape-string">
  <xsl:with-param name="s" select="local-name()"/>
  </xsl:call-template>

  <xsl:text>:null</xsl:text>
  <xsl:if test="following-sibling::*">,</xsl:if>
  <xsl:if test="not(following-sibling::*)">}</xsl:if> <!-- MBR 30.01.2010:
  added this line as it appeared to be missing from stylesheet -->
  </xsl:template>

     <!-- object -->
   <xsl:template match="*" name="base">
   <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
  <xsl:call-template name="escape-string">
  <xsl:with-param name="s" select="name()"/>
   </xsl:call-template>
  <xsl:text>:</xsl:text>
  <xsl:apply-templates select="child::node()"/>
  <xsl:if test="following-sibling::*">,</xsl:if>
  <xsl:if test="not(following-sibling::*)">}</xsl:if>
  </xsl:template>

     <!-- array -->
   <xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and 
   count(../*)&gt;1]">
 <xsl:if test="not(preceding-sibling::*)">[</xsl:if>

  <xsl:choose>
  <xsl:when test="not(child::node())">
    <xsl:text>null</xsl:text>
  </xsl:when>
  <xsl:otherwise>
    <xsl:apply-templates select="child::node()"/>
  </xsl:otherwise>
  </xsl:choose>
  <xsl:if test="following-sibling::*">,</xsl:if>
  <xsl:if test="not(following-sibling::*)">]
  </xsl:if>
  </xsl:template>

 <!-- convert root element to an anonymous container -->

 <xsl:template match="/">
  <xsl:apply-templates select="node()"/>

 </xsl:template>
  </xsl:stylesheet>

0 个答案:

没有答案