您好,我正在嘗試以使用者可以定義時間的方式將天氣資料從 XML(芬蘭天氣服務 - https://en.ilmatieteenlaitos.fi/open-data-manual-fmi-wfs-services )獲取到 JMP時期。我的程式碼不起作用,我總是收到「無效的 HTTP 請求狀態」錯誤訊息。
// User-defined start and end dates (modify as needed)
startDate = "2024-07-10";
endDate = "2024-07-24";
// Construct the URL with user-defined dates and parameters
url = "https://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::timevaluepair&place=helsinki-vantaa_airport×tep=1&starttime=" || startDate || "T00:00:00Z&endtime=" || endDate || "T23:59:59Z¶meters=temperature%2Chumidity%2Cpressure";
// Create HTTP request object
httpRequest = New HTTP Request();
// Send HTTP GET request
response = httpRequest << Send("GET", url);
// Check if the request was successful
If(response << Get Status Code == 200,
// Parse the XML response
xmlResponse = response << Get As XML,
// Extract data from XML response
dataNodes = xmlResponse << XPath("//wml2:MeasurementTVP"),
// Initialize lists to store data
temperatureList = {},
humidityList = {},
pressureList = {},
// Loop through each data node and extract values
ForEach(node in dataNodes,
// Extract timestamp
timestamp = node << XPath("wml2:time"),
// Extract temperature value
temperature = node << XPath("wml2:value[@parameter='temperature']"),
temperatureValue = temperature << NodeText,
// Extract humidity value
humidity = node << XPath("wml2:value[@parameter='humidity']"),
humidityValue = humidity << NodeText,
// Extract pressure value
pressure = node << XPath("wml2:value[@parameter='pressure']"),
pressureValue = pressure << NodeText,
// Convert timestamp to JMP DateTime format
timestampDT = Parse DateTime(timestamp, "YYYY-MM-DDThh:mm:ssZ"),
// Append data to lists
Append(temperatureList, {timestampDT, As Number(temperatureValue)}),
Append(humidityList, {timestampDT, As Number(humidityValue)}),
Append(pressureList, {timestampDT, As Number(pressureValue)})
);
// Create a new JMP data table and add columns
dt = New Table("Helsinki-Vantaa Weather Data",
Add Rows(Num Rows(temperatureList)),
New Column("Timestamp", Numeric, "DateTime"),
New Column("Temperature (°C)", Numeric, "Continuous", Format(3)),
New Column("Relative Humidity (%)", Numeric, "Continuous", Format(3)),
New Column("Pressure (hPa)", Numeric, "Continuous", Format(3))
);
// Populate the data table with values
dt:"Timestamp" << Set Values(temperatureList);
dt:"Temperature (°C)" << Set Values(humidityList);
dt:"Relative Humidity (%)" << Set Values(pressureList);
dt:"Pressure (hPa)" << Set Values(pressureList);
// Show the data table
dt << Show;
,
// Display error if request failed
Throw("Failed to fetch data. HTTP status code: " || Char(response << Get Status Code))
);新 HTTP 請求的語法不正確。這是應該返回一些數據的小範例
Names Default To Here(1);
startDate = "2024-07-10";
endDate = "2024-07-11";
// Construct the URL with user-defined dates and parameters
url = "https://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::timevaluepair&place=helsinki-vantaa_airport×tep=1&starttime=" || startDate || "T00:00:00Z&endtime=" || endDate || "T23:59:59Z¶meters=temperature%2Chumidity%2Cpressure";
// Create HTTP request object
request = New HTTP Request(
Method("GET"),
URL(url)
);
data = request << send;
/*
Show(request << Get MIME Type);
*/感謝@jthi, HTTP 請求現在可以工作,但腳本的其餘部分似乎也有錯誤。這是我第一次嘗試從 XML 取得資料。
看來你正在使用LLM生成的cod?如果是這樣,我認為他們對 JSL 的態度很糟糕。
我建議您將結果資料儲存為 xml 檔案並使用 JMP 的預覽來取得來源腳本

這需要一些嘗試,但可以用它來解析(或可以使用XPath Query()或Parse XML() )

然後,您可以使用來源腳本進一步自動化您的流程,最終可以獲得類似的結果


下面是我使用的腳本(我之前在 JMP 中使用了 Ilmatieteenlaitos 開放數據,但我認為我要么使用了不同的數據,要么以稍微不同的方式解析了它)。它確實使用了一些更高級的技術,例如 open(char to blob(), "text"),但可以透過先將檔案儲存為文字檔案來避免這種情況。它還具有資料清理和圖形創建功能(驗證它創建的資料是否正確,我沒有對此進行任何檢查)。
看更多...
Names Default To Here(1);
/*
https://en.ilmatieteenlaitos.fi/open-data
https://en.ilmatieteenlaitos.fi/open-data-manual-accessing-data
*/
location = "helsinki-vantaa_airport";
start_date = "2024-07-10";
end_date = "2024-07-11";
fmi_url = "https://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::timevaluepair&place=^location^×tep=1&starttime=^start_date^T00:00:00Z&endtime=^end_date^T23:59:59Z¶meters=temperature%2Chumidity%2Cpressure";
// Create HTTP request object
request = New HTTP Request(
Method("GET"),
URL(Eval Insert(fmi_url))
);
data = request << send;
dt = Open(
Char to blob(data),
XML Settings(
Stack(0),
Row(
"/wfs:FeatureCollection/wfs:member/omso:PointTimeSeriesObservation/om:result/wml2:MeasurementTimeseries/wml2:point"
),
Col(
"/wfs:FeatureCollection/wfs:member/omso:PointTimeSeriesObservation/om:result/wml2:MeasurementTimeseries/@gml:id",
Column Name(
"MeasurementID"
),
Fill("Use Forever"),
Type("Character"),
Format({"Best"}),
Modeling Type("Continuous")
),
Col(
"/wfs:FeatureCollection/wfs:member/omso:PointTimeSeriesObservation/om:result/wml2:MeasurementTimeseries/wml2:point/wml2:MeasurementTVP/wml2:time",
Column Name(
"Timestamp"
),
Fill("Use Once"),
Type("Character"),
Format({"Best"}),
Modeling Type("Continuous")
),
Col(
"/wfs:FeatureCollection/wfs:member/omso:PointTimeSeriesObservation/om:result/wml2:MeasurementTimeseries/wml2:point/wml2:MeasurementTVP/wml2:value",
Column Name(
"Value"
),
Fill("Use Once"),
Type("Numeric"),
Format({"Best"}),
Modeling Type("Continuous")
)
),
XML Wizard(0),
"text"
);
For Each Row(dt,
:MeasurementID = Word(-1, :MeasurementID, "-");
:Timestamp = Substitute(:Timestamp, "Z", "");
);
Column(dt, "Timestamp") << Data Type(Numeric) << Modeling Type(Continuous) << Format("yyyy-mm-ddThh:mm:ss", 19, 0);
dt_split = dt << Split(
Split By(:MeasurementID),
Split(:Value),
Group(:Timestamp),
Output Table("FMI " || location),
Sort by Column Property
);
Close(dt, no save);
dt_split << Delete Scripts(dt_split << Get Table Script Names);
gb = dt_split << Graph Builder(
Size(857, 524),
Show Control Panel(0),
Variables(X(:Timestamp), Y(:humidity), Y(:pressure), Y(:temperature)),
Elements(Position(1, 1), Line(X, Y, Legend(15))),
Elements(Position(1, 2), Line(X, Y, Legend(16))),
Elements(Position(1, 3), Line(X, Y, Legend(17)))
);
gb << Save Script to Data Table("Plot");
If you wish to see how I filled XML Wizard, you can change the XML Wizard(0), to XML Wizard(1), and run code until that point. You can then see the settings in the GUI I used. And here is some sort of explanation of what those mean

只需使用 Tall Guess,您就可以走得很遠

但它會錯過測量類型,您必須進行我所做的一些更改才能在所有行上重複它們(您也可以填充一次 -> 在 JMP 表中填充其餘部分)。
我之前嘗試過 JMP 中的導入 XML 插件,但我迷失了它,但是,現在根據您的解釋,我了解它是如何工作的! @jthi謝謝你!另外,我真的很感激您分享了使用open(char to blob(), "text") 來取得這些資料的方式!