2011-02-28 152 views
2

有人可以幫助我改進嗎?一定有更好的方法。我正在做的是構建一個本地Web服務,以便爲了填充樹菜單而獲取flex。作爲我稱爲Web服務的應用程序的Flex只是一些背景,但與問題無關。使用ColdFusion創建分層xml結構

爲了爲這棵樹創建分層數據,我編寫了以下代碼。

<cffunction name="getFormsBinMenu" access="remote" returntype="string"> 
    <cfquery name="getParents" datasource="db_intranet_data"> 
     SELECT * FROM formsbin_categories WHERE parentid = 1 ORDER BY sortorder ASC 
    </cfquery> 

    <cfoutput> 
     <cfxml variable="formsBinMenu"> 
      <?xml version='1.0' encoding='utf-8' ?> 
      <folder label="Forms Bin"> 
       <cfloop query="getParents"> 
        <folder label="#XMLFormat(getParents.catname)#"> 
          <cfquery name="getSubParents" datasource="db_intranet_data"> 
           SELECT * FROM formsbin_categories WHERE parentid = #catid# and testonly = 0 and visible = 1 ORDER BY sortorder ASC 
          </cfquery> 
          <cfloop query="getSubParents"> 
           <folder label="#XMLFormat(getSubParents.catname)#"> 
              <cfquery name="getNextSubParents" datasource="db_intranet_data"> 
               SELECT * FROM formsbin_categories WHERE parentid = #catid# and testonly = 0 and visible = 1 ORDER BY sortorder ASC 
              </cfquery> 
              <cfloop query="getNextSubParents"> 
               <folder label="#XMLFormat(getNextSubParents.catname)#"/> 
              </cfloop>       
           </folder> 
          </cfloop>           
        </folder> 
       </cfloop> 
      </folder> 
     </cfxml> 
    </cfoutput> 

    <cfset menu = #toString(formsBinMenu)#> 
    <cfreturn menu> 
</cffunction> 

正如你所看到的,我只是循環不同的查詢。雖然這適用於我的目的,但我怎麼編碼它,以便沒有太多的代碼重複?

我想過檢查看結構會有多少層次,然後在索引循環中運行它,但仍然看起來太多開銷。

任何建議將是偉大的!

回答

2

看看我用XSLT轉換創建的代碼,我敢肯定,你可以使用相同的方法在你的代碼(注意,我查詢的parentID是brandID的外鍵):

<cfquery name="queryBrands" datasource="#dsn#"> 
    SELECT brandID, brand, isAssignable, isnull(parentID, 0) AS parentID, abbreviation 
    FROM dbo.BrandTree 
</cfquery> 


<cfxml variable="rawNodeTree"> 
    <cfoutput> 
     <nodes> 
      <cfloop query="queryBrands"> 
       <node id="#queryBrands.brandID#" 
         parentID="#queryBrands.parentID#" 
         name="#XmlFormat(queryBrands.brand)#" 
         isAssignable="#queryBrands.isAssignable#" 
         abbreviation="#queryBrands.abbreviation#" /> 
      </cfloop> 
     </nodes> 
    </cfoutput> 
</cfxml> 

<cfxml variable="xslt"> 
    <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:template match="/nodes"> 
      <nodes> 
       <xsl:call-template name="getChildNodes" /> 
      </nodes> 
     </xsl:template> 

     <xsl:template name="getChildNodes"> 
      <xsl:param name="parentID" select="0" /> 

      <xsl:for-each select="//node[ @parentID = $parentID ]"> 
       <xsl:sort select="@name" /> 

       <node id="{@id}" 
         parentID="{@parentID}" 
         name="{@name}" 
         isAssignable="{@isAssignable}" 
         abbreviation="{@abbreviation}"> 
         <xsl:call-template name="getChildNodes"> 
         <xsl:with-param name="parentID" select="@id" /> 
         </xsl:call-template> 
       </node> 
      </xsl:for-each> 
     </xsl:template> 
    </xsl:transform> 
</cfxml> 

<cfset result = xmlTransform(rawNodeTree, xslt) /> 

我相信當我研究如何解決這個問題時,我用http://www.bennadel.com/blog/1080-Recursive-XSLT-For-Nested-XML-Nodes-In-ColdFusion.htm來幫助我。

另一種選擇是使用CTE進行查詢,然後使用該字段來構建您的XML。 (如果你使用ms sql服務器)

+0

我似乎無法讓你的代碼工作。必須是我沒有抓住的東西。這是我的結果:<?xml version =「1.0」encoding =「UTF-8」?> 2011-02-28 22:14:11

+0

@Robb - 我的表中有parentID爲null的項目是根節點。注意isnull將parentID設置爲0,則。你使用什麼版本的Coldfusion? – 2011-02-28 22:26:01

+0

9標準。當我轉儲rawNodeTree時,它正在傾銷我所期望的所有reocrds。只是一個示例: 2011-02-28 22:28:15