【问题标题】:CFCase values with spaces are not found未找到带空格的 CFCase 值
【发布时间】:2018-03-15 05:30:18
【问题描述】:

由于任何人在从 html 文件中解析并设置 <cfcase> 值中包含空格的值时遇到此问题吗?如果值包含空格,ColdFusion 无法在解析的 html 文件中找到匹配的数据。

例如:

<CFCASE value="LGT RAIN">
<CFSET application.condition="Lt Rain">
</CFCASE>`

html 文件的值是“LGT RAIN”,但由于其解析方式,它没有定义城市的状况。是否有解决方法,例如在运行 switch 语句之前检查条件?就像如果找到“LGT RAIN”然后将 cfset 值设置为“LGTRAIN”。

这是我正在解析的示例link

https://forecast.weather.gov/product.php?site=CAE&issuedby=CAE&product=RWR&format=CI&version=1

<CFSET WeatherData = CFHTTP.FileContent>

代码:

<!--- Check For Condition with Two Word Phrase ---------------> 
<CFSET condition= #GetToken("#content#",#attributes.citystring# + 1, " ")#>
<br> 
<CFSET city = #attributes.citystring#> 
<CFIF (condition is "LGT") 
   or (condition is "HVY") 
   or (condition is "FRZ") 
   or (condition is "MIX") 
   or (condition is "NOT")> 
  <CFSET condition= ( 
    #GetToken("#content#",#attributes.citystring# + 1, " ")# 
    & " " & 
    #GetToken("#content#",#attributes.citystring# + 2, " ")#
  )>
  <br>
  <CFSET Temp = #GetToken("#content#",#attributes.citystring# + 3, " ")#>'
  .......

【问题讨论】:

  • 你确定字符是空格吗?它似乎在这里工作正常 - trycf.com/gist/906f90ab7aeed217e583e6ea6469b9c0/… 除非它确实是 ColdFusion 8 的问题。如果是这样,也许你可以用它作为升级到受支持版本的最后一根稻草。
  • 你用什么代码来解析天气文件?我猜要么(就像 Miguel 说的那样)“LGT RAIN”中的空格并不是真正的空格字符,或者您的搜索文本有一个前导或尾随。能否提供更多示例代码?
  • @WSC27 是的,我已经看到了您之前发布的链接,但这并没有向我们展示您的代码“看到”的内容。如果您不提供更多详细信息,我们将无法帮助您。正如当前发布的那样,您共享的少量代码没有问题。所以我们只能假设是数据或者你的代码在解析数据。
  • @WSC27 - 故障排除的一个重要步骤是学习如何创建short but complete programs。当您遇到这样的问题时,首先创建一个 standalone 示例,其中包含重现问题所需的 smallest 代码量。这样做的过程通常可以帮助您自己找出问题所在。但是,即使没有,您现在也有一个完整的示例,其他人可以在他们自己的机器上进行测试,并且.. 其他人越容易测试您的代码,您得到答案的速度就越快。跨度>
  • 另外,我相信这是XY Problem

标签: coldfusion html-parsing case coldfusion-8


【解决方案1】:

有很多关于您最终要对获得的天气做什么的上下文缺失,所以我对解析天气块的方法做了几个假设。

您必须实际解析页面以获取实际块,但是一旦您这样做了,您可以使用我在下面的建议来拆分这些天气元素。我摆脱了getToken() 电话,因为我认为这可能比您需要的工作更多,并且基本上导致了空格问题。我的代码仍然比我预期的要冗长,但我试图确保我没有使用任何高于 CF8 的东西。我认为应该都可以,但是我没有 CF8 服务器可以测试。

https://trycf.com/gist/1993243eb476a629ec25f8c6e8ddff3c/acf?theme=monokai

我在代码中添加了一些注释。

<!--- Create a block of the parsed weather. --->
<cfsavecontent variable="myWX">ANDERSON       FAIR      49  16  26 W12G20    30.01F
LIBERTY        FAIR      49  14  24 W12G21    29.99F
SPARTANBURG    FAIR      45   9  23 NW12G21   30.00F
CLEMSON        FAIR      48  10  21 NW13G22   30.02F
GREENVILLE     FAIR      48  13  24 VRB3      29.99F
GREENWOOD      FAIR      49  13  23 W10G21    30.03F
GREER          FAIR      48   9  20 VRB7      29.99F
ROCK HILL      FAIR      46  17  31 NW10G22   29.99F
CHESTER        FAIR      45  12  26 W12G17    30.01F
LAURENS        FAIR      48  16  27 NW12G18   30.01F
</cfsavecontent>

 <!--- end of line character (this may change if your feed uses other eol)--->
<cfset crlf = chr(13)&chr(10)>

<!--- Make weather an array of strings for each city. --->
<cfset wxArray = ListToArray(myWX, crlf, false, true)> 

我的建议是将不同的元素放在一个结构中,然后使用它。 1 行城市天气 = 1 行 Struct。

我下面的代码假设您正在解析来自 HTML 的 65 个字符的固定宽度记录的行,这就是当您获得各个行时的样子。

<!--- Loop through the new weather array and make a new array of parsed weather. --->
<!--- Create initial weather array for output. --->
<cfset newWXArray = []> 
<cfloop array="#wxArray#" index="wxRow">
    <!--- NOTE: Yay go CF8s implicit struct creation! --->
    <cfset WXRow = {
        city = trim(mid(wxRow,1,15)) , <!--- trim() will remove leading/trailing spaces --->
        sky  = trim(mid(wxRow,16,10)) ,
        tmp  = trim(mid(wxRow,26,4)) ,
        dp   = trim(mid(wxRow,30,4)) ,
        rh   = trim(mid(wxRow,34,3)) ,
        wind = trim(mid(wxRow,37,10)) ,
        pres = trim(mid(wxRow,47,6)) , 
        rmks = trim(mid(wxRow,53,11))
    }>
    <!--- ArrayAppend() returns true/false, so this variable isn't used. --->
    <cfset throwaway = ArrayAppend(newWXArray, WXRow)>
</cfloop>

<cfdump var="#newWXArray#">

现在您拥有所有城市的数组,并且可以为您需要的城市拉出各个部分。

What's the weather like in Liberty? <br>

<cfset whichRow = 0> 
<cfloop from="1" to="#arrayLen(newWXArray)#" index="i"> 
    <cfif newWXArray[i].CITY IS "LIBERTY"> 
        <cfset whichRow = i> 
    </cfif> 
</cfloop> 

<cfoutput>
City >> #newWXArray[whichRow].CITY# <br>
Sky >> #newWXArray[whichRow].SKY# <br>
Temp >> #newWXArray[whichRow].TMP# <br>
DewPoint >> #newWXArray[whichRow].DP# <br>
Relative Humidity >> #newWXArray[whichRow].RH# <br>
Wind >> #newWXArray[whichRow].WIND# <br>
Pressure >> #newWXArray[whichRow].PRES# <br>
Remarks >> #newWXArray[whichRow].RMKS# <br>
</cfoutput>

最后说明:

我忘记了 CF8 有多么有限。如果您能够升级到当前版本的 ACF 或 Lucee,您可以做很多事情来让这MUCH 变得更容易。

另外,正如我所建议的,更改链接以提取纯文本版本 (https://forecast.weather.gov/product.php?site=CAE&issuedby=CAE&product=RWR&format=txt&version=1&glossary=1) 将显着减少您必须解析的文本量。

【讨论】:

  • WSC27 - 是的,请尽可能升级,因为original issue 导致官方 api 出现问题可能与 CF8 使用的过时 jvm 有关。 @Shawn - 甚至不记得 CF8 支持的隐式数组/结构!找不到原始文档,但 this blog 说 CF8 的 ListToArray 不支持 multicharacterdelim 参数。
  • 噢!再一次,我忘记了 CF8 有多少令人头疼的事情导致了一些现在很容易被视为理所当然的事情。我查看了我在 CF4.0 时代编写的一些早期代码,并想现在我为什么要这样做?......哦,是的。”
【解决方案2】:

我对文本数据中的空格弄乱条件逻辑的经验是尾随空格,但原理是相同的。如有疑问,请查看您的数据。这是一个简单的例子:

MyVar = 'Lgt  Rain';  // two spaces between the words
if (MyVar == 'Lgt Rain'){ // one space between words
applicable code
}
else {
writeoutput(replace(MyVar, ' ', '-space-', 'all'));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 2016-03-26
    相关资源
    最近更新 更多