有人可以帮我改进吗?一定有更好的方法。我正在做的是构建一个本地Web服务,以便flex来抓取以填充树状菜单。作为我正在调用Web服务的应用程序的Flex只是一些背景,但与问题无关。
为了为这棵树创建分层数据,我编写了以下内容。
<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>
正如您所看到的,我只是循环遍历不同的查询。虽然这适用于我的目的,我怎么能编码它,以便没有那么多的代码重复?
我考虑过检查结构的深度是多少,然后在索引循环中运行它,但这似乎仍然是太多开销。
任何建议都会很棒!
答案 0 :(得分: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 server)