在ColdFusion中从XML输出HTML

时间:2017-01-27 21:20:53

标签: html xml coldfusion

我有一个查询正在运行以收集邻接列表,然后生成该列表的XML对象作为树。接下来,我需要将该树输出为简单的HTML。

我希望我的XML文档输出为:

<ul>
 <li margin="5">Title
  <ul>
   <li margin="10">Title</li>
  </ul>
 </li>
</ul>

以下是我目前编码的内容:

<cfquery name="nodeTable" datasource="#database.ds#">
  SELECT [mc_location].[id],[mc_location].[title], [mc_location].[parent_id] FROM [mc_location]
  LEFT JOIN [mc_location_type] ON [mc_location].[id] = [mc_location_type].[location_id]
  WHERE [mc_location_type].[category] = 'staff'
</cfquery>

<cffunction name="outputChildNodes" access="public" returntype="void" output="true">
  <cfargument name="nodeTable" type="query" required="true" hint="I am the node query object."/>
  <cfargument name="parent_id" type="numeric" required="false" default="0"/>
    <cfset var local = {}/>
    <cfquery name="local.childNodes" dbtype="query">
    SELECT id, parent_id, title
    FROM arguments.nodeTable
    WHERE parent_id = <cfqueryparam value="#arguments.parent_id#" cfsqltype="cf_sql_integer" />
      ORDER BY id ASC
    </cfquery>

    <cfloop query="local.childNodes">
    <child id="#local.childNodes.id#" parent-id="#local.childNodes.parent_id#" name="#local.childNodes.title#">
     <cfset outputChildNodes(arguments.nodeTable, local.childNodes.id)/>
    </child>
    </cfloop>
    <cfreturn/>
</cffunction>

<!--- Build the node XML document recursively. --->

<cfxml variable="nodeTree">
    <childern>
        <!--- Output the root-level nodes. --->
        <cfset outputChildNodes( nodeTable ) />
    </childern>
</cfxml>

<!--- Render the XML document. --->
<cfloop index="childern" array="#nodeTree.childern#">
  <cfloop index="child" array="#childern#">
    <cfif isStruct(child.XmlAttributes)>
      <cfdump var="#child[1].XmlAttributes#"/>
    </cfif>
  </cfloop>
</cfloop>

谢谢!

1 个答案:

答案 0 :(得分:0)

我遇到的问题与未正确定义变量范围有关(例如在cfset中使用&#34; var&#34;使用arguments.parameter等),这是递归调用函数所必需的。以下是一个简短的解决方案。

<!--- query for parent child tree --->
<cfquery name="tree_nodes" datasource="#sonis.ds#">
  SELECT [location].[id],[location].[title], [location].[parent_id] FROM [location]
  LEFT JOIN [location_category] ON [location].[id] = [location_category].[location_id]
  WHERE [location_category].[category] = 'staff'
</cfquery>

<!--- build tree from adjacency list function --->
<cffunction name="build_tree" access="public" output="true">
  <cfargument var name="tree_nodes" type="query" required="true"/>
  <cfargument var name="parent_id" type="numeric" required="false" default="0"/>
  <cfargument var name="depth" type="numeric" required="false" default="0"/>
  <cfset var local = {}/>
    <cfquery name="local.child_node" dbtype="query">
    SELECT id, parent_id, title
    FROM arguments.tree_nodes
    WHERE parent_id = <cfqueryparam value="#arguments.parent_id#" cfsqltype="cf_sql_integer" />
      ORDER BY id ASC
    </cfquery>
  <cfset var branch = {}/>
  <cfset var counter = 1/>
  <cfloop query="local.child_node">
    <cfset local.depth = arguments.depth/>
    <cfset branch[counter++] = {
      'id' = '#local.child_node.id#',
      'title' = '#local.child_node.title#',
      'parent_id' = '#local.child_node.parent_id#',
      'depth' = local.depth,
      'children' = build_tree(arguments.tree_nodes, local.child_node.id,++local.depth)
    } />
    </cfloop>
    <cfreturn branch/>
</cffunction>

<!--- print tree as select box function --->
<cffunction name="print_tree_select" access="public" output="true">
  <cfargument var name="tree" type="struct" required="true"/>
  <cfargument var name="selected" type="numeric" required="false" default="0"/>
  <cfargument var name="child" type="numeric" required="false" default="0"/>
  <cfif child eq '0'><select name="select_tree"><option value="null"></option></cfif>
  <cfloop from="1" to="#StructCount(arguments.tree)#" index="a">
    <option value="#arguments.tree[a]['id']#"<cfif #arguments.selected# eq #arguments.tree[a]['id']#> selected</cfif>>
      <cfif #arguments.tree[a]['depth']# GT 0>
        #RepeatString('--', arguments.tree[a]['depth'])#&nbsp;
      </cfif>
      #arguments.tree[a]['title']#
    </option>
    <cfif StructKeyExists(arguments.tree[a], 'children') AND StructCount(arguments.tree[a]['children']) GT 0>
      #print_tree_select(arguments.tree[a]['children'],arguments.selected, 1)#
    </cfif>
  </cfloop>
  <cfif child eq '0'></select></cfif>
</cffunction>

<!--- print tree as list function --->
<cffunction name="print_tree_list" access="public" output="true">
  <cfargument var name="tree" type="struct" required="true"/>
  <ul style="list-style-type: circle;">
    <cfloop from="1" to="#StructCount(arguments.tree)#" index="local.i">
        <li>
          <cfform method="post" name="edit">
            #arguments.tree[local.i]['title']#
            <cfinput type="hidden" name="id" value="#arguments.tree[local.i]['id']#"/>
            <cfinput type="Submit" name="command" value="Edit"/>
          </cfform>
          <cfif StructKeyExists(arguments.tree[local.i], 'children') AND StructCount(arguments.tree[local.i]['children']) GT 0>
            #print_tree_list(arguments.tree[local.i]['children'])#
          </cfif>
        </li>
    </cfloop>
  </ul>
</cffunction>