重新格式化从SharePoint API直接返回的 XML

If you use the SPSiteDataQuery to get XML from SharePoint the results are easy to use with XSL. The format of the XML would be similar to the following...

<rows>
  <row>
    <Title>Page 1</Title>
    <ContentType>Page</ContentType>
    <ID>1</ID>
  </row>
  <row>
    <Title>Page 2</Title>
    <ContentType>Page</ContentType>
    <ID>2</ID>
  </row>
</rows>

However if you use the API directly (SPContext.Current.List.Items.Xml) to get the rows from a list the XML is somewhat different...

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
     xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
     xmlns:rs='urn:schemas-microsoft-com:rowset'
     xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
   <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
      <s:AttributeType name='ows_Title' rs:name='Title' rs:number='11'>
         <s:datatype dt:type='string' dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_ContentType' rs:name='Content Type' rs:number='27'>
         <s:datatype dt:type='string' dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_ID' rs:name='ID' rs:number='37'>
         <s:datatype dt:type='i4' dt:maxLength='4' />
      </s:AttributeType>
   </s:ElementType>
</s:Schema>
<rs:data ItemCount="2">
   <z:row ows_ContentType='Page' ows__ID='1' ows_Title='Page 1' />
   <z:row ows_ContentType='Page' ows__ID='2' ows_Title='Page 2' />
</rs:data>
</xml>

This a cut down version and whilst it is entirely possible to render this using XSL, it does mean defining namespaces and having to use the ows_ prefix on the attributes. Experienced XSL developers would have no problem with this, but it can be confusing for others. To get around this problem you can pre-process your XML with another XSL, before passing it to the final XSL tranformation.

The XSL below will tranform the complicated XML above into a much more user friendly version, similar to the first example. This not only makes the XSL easier to read & write, it also means the XSL can be re-used on XML returned from the SPSiteDataQuery.

<xsl:stylesheet version="1.0"
     xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
     xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
     xmlns:z="#RowsetSchema">

 <s:Schema id="RowsetSchema"/>

 <xsl:output method="xml" omit-xml-declaration="yes" />

 <xsl:template match="/">
  <xsl:text disable-output-escaping="yes">&lt;rows&gt;</xsl:text>
  <xsl:apply-templates select="//z:row"/>
  <xsl:text disable-output-escaping="yes">&lt;/rows&gt;</xsl:text>
 </xsl:template>

 <xsl:template match="z:row">
  <xsl:text disable-output-escaping="yes">&lt;row&gt;</xsl:text>
  <xsl:apply-templates select="@*"/>
  <xsl:text disable-output-escaping="yes">&lt;/row&gt;</xsl:text>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
  <xsl:value-of select="substring-after(name(), 'ows_')"/>
  <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>
  <xsl:value-of select="substring-after(name(), 'ows_')"/>
  <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

Now with some simple code we can transform the complicated XML into a more user friendly version...

XslCompiledTransform oTransform = new XslCompiledTransform();
XmlDocument oTidyXsl = new XmlDocument();

oTidyXsl.LoadXml(sConvertXsl);
oTransform.Load(oTidyXsl);
           
System.IO.StringWriter sw = new System.IO.StringWriter();      
XmlTextWriter tw = new XmlTextWriter(sw);

oTransform.Transform(ApiXml, null, tw);
string sConvertedXml = sw.ToString();

 

参考资料

Reformatting XML retrieved directly from the SharePoint API

posted @ 2010-09-19 15:30  Sunmoonfire  阅读(203)  评论(0编辑  收藏  举报