`
prec
  • 浏览: 63715 次
  • 性别: Icon_minigender_1
  • 来自: 互联网
最近访客 更多访客>>
社区版块
存档分类
最新评论

.NET中利用Ebay的XSLT模板转换XML到JSON

阅读更多

从XML转换到JSON的方法有多种, 不过都要依赖第三方的库来实现转化,不过有了eBay提供的xml-2-json.xlst模板,你会发现转换原来很轻松.

xml-2-json.xslt的代码大致如下(稍做了点改动):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" exclude-result-prefixes="ebl">
    
<!--====================================================================================
    Original version by : Holten Norris ( holtennorris at yahoo.com )
    Current version maintained  by: Alan Lewis (alanlewis at gmail.com)
    Thanks to Venu Reddy from eBay XSLT team for help with the array detection code
    Protected by CDDL open source license.  
    Transforms XML into JavaScript objects, using a JSON format.
    ===================================================================================== 
-->
    
<xsl:output method="text" encoding="UTF-8"/>
    
<xsl:template match="*">
        
<xsl:param name="recursionCnt">0</xsl:param>
        
<xsl:param name="isLast">1</xsl:param>
        
<xsl:param name="inArray">0</xsl:param>
        
<xsl:if test="$recursionCnt=0">
            
<xsl:text>json = {</xsl:text>
        
</xsl:if>
        
<!-- test what type of data to output  -->
        
<xsl:variable name="elementDataType">
            
<xsl:value-of select="number(text())"/>
        
</xsl:variable>
        
<xsl:variable name="elementData">
            
<!-- TEXT ( use quotes ) -->
            
<xsl:if test="string($elementDataType) ='NaN'">
                
<xsl:if test="boolean(text())">
                "
<xsl:value-of select="text()"/>"
                
</xsl:if>
            
</xsl:if>
            
<!-- NUMBER (no quotes ) -->
            
<xsl:if test="string($elementDataType) !='NaN'">
                
<xsl:value-of select="text()"/>
            
</xsl:if>
            
<!-- NULL -->
            
<xsl:if test="not(*)">
                
<xsl:if test="not(text())">
                    null
                
</xsl:if>
            
</xsl:if>
        
</xsl:variable>
        
<xsl:variable name="hasRepeatElements">
            
<xsl:for-each select="*">
                
<xsl:if test="name() = name(preceding-sibling::*) or name() = name(following-sibling::*)">
                    true
                
</xsl:if>
            
</xsl:for-each>
        
</xsl:variable>
        
<xsl:if test="not(count(@*) &gt; 0)">
         "
<xsl:value-of select="local-name()"/>": <xsl:value-of select="$elementData"/>
        
</xsl:if>
        
<xsl:if test="count(@*) &gt; 0">
        "
<xsl:value-of select="local-name()"/>": {
        "content": 
<xsl:value-of select="$elementData"/>
            
<xsl:for-each select="@*">
                
<xsl:if test="position()=1">,</xsl:if>
                
<!-- test what type of data to output  -->
                
<xsl:variable name="dataType">
                    
<xsl:value-of select="number(.)"/>
                
</xsl:variable>
                
<xsl:variable name="data">
                    
<!-- TEXT ( use quotes ) -->
                    
<xsl:if test="string($dataType) ='NaN'">
                "
<xsl:value-of select="current()"/></xsl:if>
                    
<!-- NUMBER (no quotes ) -->
                    
<xsl:if test="string($dataType) !='NaN'">
                        
<xsl:value-of select="current()"/>
                    
</xsl:if>
                
</xsl:variable>
                
<xsl:value-of select="local-name()"/>:<xsl:value-of select="$data"/>
                
<xsl:if test="position() !=last()"></xsl:if>
            
</xsl:for-each>
        }
        
</xsl:if>
        
<xsl:if test="not($hasRepeatElements = '')">
                    [{
                
</xsl:if>
        
<xsl:for-each select="*">
            
<xsl:if test="position()=1">
                
<xsl:if test="$hasRepeatElements = ''">
                    
<xsl:text> { </xsl:text>
                
</xsl:if>
            
</xsl:if>
            
<xsl:apply-templates select="current()">
                
<xsl:with-param name="recursionCnt" select="$recursionCnt+1"/>
                
<xsl:with-param name="isLast" select="position()=last()"/>
                
<xsl:with-param name="inArray" select="not($hasRepeatElements = '')"/>
            
</xsl:apply-templates>
            
<xsl:if test="position()=last()">
                
<xsl:if test="$hasRepeatElements = ''">
                    
<xsl:text> } </xsl:text>
                
</xsl:if>
            
</xsl:if>
        
</xsl:for-each>
        
<xsl:if test="not($hasRepeatElements = '')">
                    }]
                
</xsl:if>
        
<xsl:if test="not( $isLast )">
            
<xsl:if test="$inArray = 'true'">
                
<xsl:text> } </xsl:text>
            
</xsl:if>
            , 
            
<xsl:if test="$inArray = 'true'">
                
<xsl:text> { </xsl:text>
            
</xsl:if>
        
</xsl:if>
        
<xsl:if test="$recursionCnt=0"> }; </xsl:if>
    
</xsl:template>
</xsl:stylesheet>

 从上面的代码可以看出,只要给出相应的XML在应用此XLST样式就可以实现转化了。

不过为了方便,还是封装一层,以便我们能更好地在.NET下完成任务:

首先,是一个通用的转换方法,它可以读出流,然后应用XSLT样式:

 

private static string XML2JSon(Stream rd,int type) 
        
...{
            XmlDocument doc 
= new XmlDocument();
            rd.Position
=0;
            doc.Load(rd);

            XmlElement root 
= doc.DocumentElement;
            XmlNodeList nl;
            
if(type == 0)
                 nl 
= root.SelectNodes("//Table1");
            
else
                 nl 
= root.ChildNodes;
            XmlDocument srcdoc 
= new XmlDocument();
            
string temp =null;
            
foreach(XmlNode xn in nl) 
            
...{
                
if(type==0)
                    temp 
+= xn.InnerXml;
                
else
                    temp 
+= xn.OuterXml;
            }

            temp 
= "<result>" + temp + "</result>";
            srcdoc.InnerXml 
= temp;

            XPathNavigator nav 
= srcdoc.CreateNavigator();

            XslTransform xt 
= new XslTransform();

            
string path = ConfigurationSettings.AppSettings["ServerPath"];
            xt.Load(path 
+ "css/xml-2-json.xsl");

            Stream w 
= new MemoryStream();
            XmlTextWriter wr 
= new XmlTextWriter(w,Encoding.GetEncoding("UTF-8"));
            xt.Transform(nav,
null,w,null);
            w.Position 
= 0;
            StreamReader tr 
= new StreamReader(w);
            
string str = tr.ReadToEnd();
            
            w.Close();
            tr.Close();
            
return str;
        }

 

然后定义三个重载方法,来负责转换或序列化对象生成XML:

 转换DataSet

        public static string Convert(DataSet ds) 
        
...{
            MemoryStream ms 
= new MemoryStream();
            XmlTextWriter tw 
= new XmlTextWriter(ms,Encoding.UTF8);
            ds.WriteXml(ms);
            
string str = XML2JSon(ms,0);
   
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics