0

メニュー項目をすばやく検索して操作したい豊富なメニューがあります。IDのリストを検索することは可能ですか?

list contains ("0,57,19,22,30,31,32,33,34,36,45,53,63,58,59,23,24,25,26,27,28,29,37,38,39,40,41,42,43,44,46,47,48,50,51,52,54,55,16", "45")

ノードの例:

<li class="standby" id="id61">

今のところ、私はcfscriptでループを使用しています

        if(listLen(IdsToRemove.List,",") GT 1){
            for(i=1;i lte listLen(IdsToRemove.List);i=i+1) {
                valueToFind="li[@id='" & listGetAt(IdsToRemove.List,i) & "']";
                findNode=XmlSearch(MyNavigation.myMenu,"//" & valueToFind);
                Instance.UDFLibrary.XmlDeleteNodes(XmlDocument=MyNavigation.myMenu,Nodes=findNode);
            }
        }

リストを検索して、すべてのノードを一度に削除したいと思っています。考え?

4

2 に答える 2

1

xpath式で使用contains()して、文字列を検索できます。その文字列をリストとして扱う場合は、外側のループをスキップできます。

var ids = ListChangeDelims(IdsToRemove.List, ',', ' '); // commas to spaces
var nodes = XmlSearch(MyNavigation.myMenu,"//li[contains(' " & ids & " ', concat(' ', substring(@id,3), ' '))]");

idは「concat(' ', substring(@id,3), ' ')05719」のようになり、「0」のようになります。したがって、上記の式は基本的に、ノードidの最初の2文字を除くすべてを使用するListFind()の長蛇の列です。

于 2012-03-26T08:31:25.367 に答える
0

他の人がこれについて助けを必要とする場合に備えて、私が使用している完全なセットアップは次のとおりです。

<cfscript>
    testme=structnew();
    testme.menu=xmlNav(buildNav(qgetNav));
    testme.menustring=tostring(xmlNav(buildNav(qgetNav)));

    testme.valueToFind="li[@id='id56']";
    testme.findNode=XmlSearch(testme.menu,"//" & testme.valueToFind);

    testme.List="0 16 41 42 43 16 41 42 43 16 41 42 43 16 41 42 43 ";
    testme.ids = ListChangeDelims(testme.List,' ',','); // commas to spaces
    testme.nodes = XmlSearch(testme.menu,"//li[contains(' " & testme.ids & " ', concat(' ', substring(@id,3), ' '))]");

    XmlDeleteNodes(XmlDocument=testme.menu,Nodes=testme.nodes);

</cfscript>
<cfdump var="#testme#">

<cffunction name="buildNav" returntype="array">
    <cfargument name="qGetNav" type="query">
    <cfset var sLU = structNew()>
    <cfset var aMenu = arrayNew(1)>
    <cfset var aNavMenuItems = arrayNew(1)>
    <cfset var sThis = structNew()>
    <cfloop query="qGetNav">
        <cfset sThis = structNew()>
        <cfset sThis.route = qGetNav.Route>
        <cfset sthis.textDesc = qGetNav.textDesc>
        <cfset sthis.linkTitle = qGetNav.linkTitle>
        <cfset sthis.linkTarget = qGetNav.linkTarget>
        <cfset sthis.Version = qGetNav.version>
        <cfif sthis.Version Eq "CB">
            <cfset arrayAppend(aNavMenuItems,sThis.route)>
        </cfif> 
        <cfset sthis.navID = qGetNav.navID> 
        <cfset sthis.aChildren = arrayNew(1)>
        <cfset sLU[qGetNav.navID]  = sThis>
        <cfif val(qGetNav.navParentID) NEQ 0>
            <cfset arrayAppend(sLU[qGetNav.navParentID].aChildren, sThis)>
        <cfelse>
            <cfset arrayAppend(aMenu, sThis)>
        </cfif>
    </cfloop>
    <cfreturn aMenu>
</cffunction>

<cffunction name="xmlNav" returntype="xml">
    <cfargument name="aNav" type="array">
    <cfset var navXML="">
    <cfxml variable="navXML">
        <cfoutput>
            #xmlNavList(aNav=arguments.aNav)#
        </cfoutput>
    </cfxml>
    <cfreturn navXML>
</cffunction>

<cffunction name="xmlNavList" returntype="any">
    <cfargument name="aNav" type="array">
    <cfargument name="level" type="numeric" default="0">
    <cfset var iNav = "">
    <ul 
        <cfif arguments.level GT 0>
            class="sub-nav-main-links nestingLevel<cfoutput>#arguments.level#</cfoutput>"
        <cfelse>
            id="nav-main-links"
        </cfif> 
        >
        <cfloop array="#aNav#" index="iNav">
            <cfoutput>
                <cfif iNav.Version Eq "CB">
                    <cfset iNav.Route="/?event=" & iNav.Route>
                <cfelseif iNav.Version Eq "L">
                    <cfset iNav.Route="http://legacy" & iNav.Route>
                </cfif> 
                <li class="standby" id="id#iNav.navid#">
                    <a href="#iNav.route#" title="#iNav.linkTitle#" target="#iNav.linkTarget#">
                        #iNav.textDesc# <font class="menuItemType">(#iNav.Version#)</font>
                    </a>
                    <cfif arrayLen(iNav.aChildren) GT 0>
                        <cfset xmlNavList(iNav.aChildren,arguments.level+1)>
                    </cfif>
                </li>
            </cfoutput>
        </cfloop>
    </ul>
</cffunction>

<cffunction name="xmlGetNodePath" access="public" returntype="string"output="false" hint="I take a given XML node and return it's full XML path.">
    <cfargument name="node" type="any" required="true" hint="I am the XML node who's location is being reverse engineered."/>
    <cfset var local={ } />
    <cfset local.fullPath="" />
    <cfset local.marker="udf:xmlGetNodePath" />
    <cfset local.node=arguments.node />
    <cfloop condition="true">
        <cfif ( !structKeyExists( local.node, "xmlParent" ) || !structKeyExists(local.node.xmlParent, "xmlName" ) )>
            <cfbreak />
        </cfif>
        <cfset local.node.xmlAttributes[ local.marker ]=true />
        <cfset local.siblings=xmlSearch( local.node.xmlParent, ( "./" & local.node.xmlName)) />
        <cfloop index="local.siblingIndex" from="1" to="#arrayLen( local.siblings )#"step="1">
            <cfif structKeyExists( local.siblings[ local.siblingIndex ].xmlAttributes,local.marker )>
                <cfset local.fullPath=( "/" & local.node.xmlName & "[" & local.siblingIndex& "]" & local.fullPath ) />
                <cfbreak />
            </cfif>
        </cfloop>
        <cfset structDelete( local.node.xmlAttributes, local.marker ) />
        <cfset local.node=local.node.xmlParent />
    </cfloop>
    <cfreturn local.fullPath />
</cffunction>

<cffunction name="XmlDeleteNodes" access="public" returntype="void" output="false" hint="I remove a node or an array of nodes from the given XML document.">
    <!--- Define arugments. --->
    <cfargument name="XmlDocument" type="any" required="true" hint="I am a ColdFusion XML document object."/>
    <cfargument name="Nodes" type="any" required="false" hint="I am the node or an array of nodes being removed from the given document." />
    <!--- Define the local scope. --->
    <cfset var LOCAL=StructNew() />
    <!---Check to see if we have a node or array of nodes. If weonly have
    one node passed in, let's create an array ofit so we can assume an array
    going forward.--->
    <cfif NOT IsArray( ARGUMENTS.Nodes )>
        <!--- Get a reference to the single node. --->
        <cfset LOCAL.Node=ARGUMENTS.Nodes />
        <!--- Convert single node to array. --->
        <cfset ARGUMENTS.Nodes=[ LOCAL.Node ] />
    </cfif>
    <!---Flag nodes for deletion. We are going to need to deletethese via
    the XmlChildren array of the parent, so weneed to be able to differentiate
    them from siblings.Also, we only want to work with actual ELEMENT nodes,not
    attributes or anything, so let's remove any nodesthat are not element nodes.--->
    <cfloop index="LOCAL.NodeIndex" from="#ArrayLen( ARGUMENTS.Nodes )#" to="1" step="-1">
        <!--- Get a node short-hand. --->
        <cfset LOCAL.Node=ARGUMENTS.Nodes[ LOCAL.NodeIndex ] />
        <!---Check to make sure that this node has an XmlChildrenelement. If it
        does, then it is an element node. Ifnot, then we want to get rid of it.--->
        <cfif StructKeyExists( LOCAL.Node, "XmlChildren" )>
          <!--- Set delet flag. --->
          <cfset LOCAL.Node.XmlAttributes[ "delete-me-flag" ]="true" />
        <cfelse>
          <!---This is not an element node. Delete it from outlist of nodes to delete.--->
          <cfset ArrayDeleteAt(ARGUMENTS.Nodes,LOCAL.NodeIndex) />
        </cfif>
     </cfloop>
    <!---Now that we have flagged the nodes that need to bedeleted, we can
    loop over them to find their parents.All nodes should have a parent, except
    for the rootnode, which we cannot delete.--->
    <cfloop index="LOCAL.Node" array="#ARGUMENTS.Nodes#">
      <!--- Get the parent node. --->
      <cfset LOCAL.ParentNodes=XmlSearch( LOCAL.Node, "../" ) />
      <!---Check to see if we have a parent node. We can'tdelete the root node,
      and we also be deleting otherelements as well - make sure it is all playingnicely
      together. As a final check, make sure thatout parent has children (only
      happens if we aredealing with the root document element).--->
      <cfif (ArrayLen( LOCAL.ParentNodes ) AND StructKeyExists( LOCAL.ParentNodes[1], "XmlChildren" ))>
            <!--- Get the parent node short-hand. --->
            <cfset LOCAL.ParentNode=LOCAL.ParentNodes[ 1 ] />
            <!---Now that we have a parent node, we want to loopover it's children
            to one the nodes flagged asdeleted (and delete them). As we do this, wewant
            to loop over the children backwards so thatwe don't go out of bounds as
            we start to removechild nodes.--->
            <cfloop index="LOCAL.NodeIndex" from="#ArrayLen( LOCAL.ParentNode.XmlChildren )#"to="1" step="-1">
                <!--- Get the current node shorthand. --->
                <cfset LOCAL.Node=LOCAL.ParentNode.XmlChildren[ LOCAL.NodeIndex ] />
                <!---Check to see if this node has been flaggedfor deletion.--->
                <cfif StructKeyExists( LOCAL.Node.XmlAttributes, "delete-me-flag" )>
                        <!--- Delete this node from parent. --->
                        <cfset ArrayDeleteAt(LOCAL.ParentNode.XmlChildren,LOCAL.NodeIndex) />
                        <!---Clean up the node by removing thedeletion flag. This node might still
                        beused by another part of the program.--->
                        <cfset StructDelete(LOCAL.Node.XmlAttributes, "delete-me-flag") />
                    </cfif>
            </cfloop>
        </cfif>
    </cfloop>
    <!--- Return out. --->
    <cfreturn />
</cffunction>
于 2012-03-26T21:21:25.483 に答える