coldfusion add an id to certain classes

烈酒焚心 提交于 2019-12-12 18:14:28

问题


Currently I have a bunch of HTML stored in a variable that I am outputting to the page that looks a little like this:

<p class="firstpara">some stuff</p>
<p class="subhead">a heading</p>
<p class="subsubhead">a subheading</p>
<p>wording and such</p>
<p class="subsubhead">another subheading</p>

you get the idea.

and is output like:

<cfoutput>
#request.oEntry.getHTMLStuff()#
</cfoutput>

Anyway, I need to find all classes of "subsubhead" and add in a id="x" where x corresponds to a database id i have for that subheading.

I think this would be best done in Coldfusion since the database id is already held in a cfquery and i Can't mix and match jQuery and ColdFusion.

not currently sure the best way to do this.


回答1:


Since you like jQuery but need to do this in CF, I suggest doing this work with the HTML parser JSOUP. JSOUP has syntax that is very similar to jQuery, but operates on the server side with java (and thus CF). After you download the jar and add it to your CF classpath, you can then use it like so:

<cfset jsoup = CreateObject("java", "org.jsoup.Jsoup")>
<cfsavecontent variable="html">
<p class="firstpara">some stuff</p>
<p class="subhead">a heading</p>
<p class="subsubhead">a subheading</p>
<p>wording and such</p>
<p class="subsubhead">another subheading</p>
</cfsavecontent>

<cfset htmlObj = jsoup.parse(html)>

<cfloop array="#htmlObj.select('.subsubhead')#" index="element">
    <cfif Find("a subheading", element.ownText())>
        <cfset element.attr("id", 1)>
    </cfif>

    <cfif Find("another subheading", element.ownText())>
        <cfset element.attr("id", 2)>
    </cfif>
</cfloop>

<cfoutput>
    <pre>
    #HTMLEditFormat(htmlObj.body().html())#
    </pre>
</cfoutput>

This outputs:

    <p class="firstpara">some stuff</p> 
<p class="subhead">a heading</p> 
<p class="subsubhead" id="1">a subheading</p> 
<p>wording and such</p> 
<p class="subsubhead" id="2">another subheading</p>

The way I'm assigning id values (via checking the p tag contents) to particular instances of subsubhead is but one option; you could also do something like match the element back up with your database query based on the order of each (the order of the element in the array and the order of the id in the query). It's up to you.




回答2:


Can the HTML fragment in question be caste to an XML document (it needs to have a root node and be XML conformant). If it can then you could use XPath or XQuery on the resulting object in ColdFusion to get all elements with a value of "subsubhead" in the class attribute and then change attribute values accordingly and then write back to a string. Example below:

<cfxml variable="htmlFragment">
  <fragment>
    <p class="firstpara">some stuff</p>
    <p class="subhead">a heading</p>
    <p class="subsubhead">a subheading</p>
    <p>wording and such</p>
    <p class="subsubhead">another subheading</p>
  </fragment>
</cfxml>

<cfset subheads = XmlSearch(htmlFragment, "//p[@class=""subsubhead""]")>

<cfloop array=#subheads# index="p">
  <cfset p.XmlAttributes.class = "newvalue">
</cfloop>

Remember in the above example to remove the fragment root node before writing back out.




回答3:


This is the code I have come up with.

<cfscript>
local.string    = request.oEntry.getEditorial();
local.x         = 0; 
do{
    local.x = REFind("Subsubhead", local.string,local.x);
    if(local.x neq 0){
        local.x = local.x+10;
        local.string = insert(" id='x'",local.string,local.x);
    }

} while(local.x neq 0);

</cfscript>

This works for me, but there might be a better way




回答4:


You might try the following. I don't think you even need a regex:

<cfset html_content = replaceNoCase(request.oEntry.getHTMLStuff(), "<p class=""subsubhead""", "<p id=""#id#"" class=""subsubhead""", "All" />
<cfoutput>#html_content#</cfoutput>

Note the double double-quotes inside the double-quotes so the strings don't break! The final parameter value to replaceNoCase() tells CF to replace all occurrences. Omit the <p portion if you're looking to replace values for this class across other tags as well. It might be advisable in that case to use a regex to avoid replacing any content (not a high chance of a match, but you never know):

<cfset html_content = REReplaceNoCase(request.oEntry.getHTMLStuff(), "(<[^>]+?)(class=\""subsubhead\"")([^>]*>)", "\1 id=""#id#"" \2 \3", "All") />

This will only replace the class="subsubhead" with id="#id#" class="subsubhead" (where #id# is the value of a CF variable) in HTML tags.

Hope this helps. This is the sort of thing that ColdFusion does quickly and easily.

UPDATE: You didn't mention in the OP whether the value of x needs to increment with each match; if that is the case, then you'll want to use REFindNoCase() with returnsubexpressions=true (using the same regex as above), then looping through the len and pos arrays:

<cfset content_match = REFindNoCase(request.oEntry.getHTMLStuff(), "(<[^>]+?)(class=\""subsubhead\"")([^>]*>)", 1, true) />
<cfloop from="1" to="#arrayLen(content_match.pos)#" index="ii">
    <!--- Do the replace in here --->
    <cfset temp = mid(content_match, pos[ii], len[ii]) />
    <cfset temp = replaceNoCase(temp, "class=""subsubhead""", "id=""#ii#"" class=""subsubhead""") />
    <cfset content_match = removeChars(content_match, pos[ii], len[ii]) />
    <cfset content_match = insert(temp, content_match, pos[ii]) />
</cfloop>

There might be an off by one error in the above (I didn't test), but I think it is generally sound.



来源:https://stackoverflow.com/questions/9771913/coldfusion-add-an-id-to-certain-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!