【发布时间】:2020-10-15 13:40:45
【问题描述】:
我无法从 xml(外部 url)文件解析到 php。我想要完成的想法是我的 .php 脚本加载 url 并从中获取特定数据 -> 将它们解析为变量,然后使用这些变量将它们发布到我的数据库(MySQL)。
我的问题(可能是错误的,因为处理 XML 数据的新功能和 PHP 的新功能)与“foreach”循环有关。当我打开脚本时,它会为我返回以下数据:
1
Array
Array
Array
2
Array
Array
Array
3
当然,在最终版本中(当我开始工作时),我没有必要打印/回显这些值,因为这些变量将发布到我的数据库中。所以请记住,我现在正在执行此操作,了解代码以及问题可能出在哪里。
$url = 'http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::daily::simple&place=tammela&starttime='.$first_image_date.'T00:00:00Z&endtime='.$last_image_date.'T01:00:00Z¶meters=tmin,tday,tmax&';
Original xml url = http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::daily::simple&place=tammela&starttime=2020-05-24T00:00:00Z&endtime=2020-05-31T01:00:00Z¶meters=tmin,tday,tmax&
以下变量是我从中获取 XML 数据的地方。只有 $first_image_date 和 $last_image_date 会改变(无论何时使用 php)。所以基本的想法是我的服务器上有图像,现在我有 9 种不同的图像(它们都是 .jpg 格式),.php 代码从这些图像中获取日期并与 XML 数据匹配。
如果新图片上传/传输到我的服务器,这意味着 $url 变量将同时获取链接到 url 的更新日期的数据。
<?php
$folder_location = "AarniAnsa/*/*/";
$jpg = glob("" . $folder_location . "*.jpg");
$first_image = reset($jpg);
$last_image = end($jpg);
ob_start();
print end(explode('@',$first_image,-2));
$first_image_date = ob_get_contents();
ob_end_clean();
ob_start();
print end(explode('@',$last_image,-2));
$last_image_date = ob_get_contents();
ob_end_clean();
define('DB_SERVER', '***');
define('DB_USERNAME', '***');
define('DB_PASSWORD', '***');
define('DB_NAME', '***');
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if($link === false) {
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// Alla oleva linkki antaa pelkästään meille tmin (Alin lämpötila), tday (Keskilämpötila) sekä tmax (Ylin lämpötila) arvot. Muita muuttujia emme tarvitse.
$url = 'http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::daily::simple&place=tammela&starttime='.$first_image_date.'T00:00:00Z&endtime='.$last_image_date.'T01:00:00Z¶meters=tmin,tday,tmax&';
$xml = simplexml_load_file($url);
$xmlID = 0;
$xml->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs/2.0');
$xml->registerXPathNamespace('BsWfs', 'http://xml.fmi.fi/schema/wfs/2.0');
foreach ($xml->xpath('//wfs:member/BsWfs:BsWfsElement') as $xmlData) {
$xmlID++;
echo $xmlID;
echo "<br>";
$xmlDate = $xmlData->xpath('BsWfs:Time');
echo $xmlDate;
echo "<br>";
$xmlName = $xmlData->xpath('BsWfs:ParameterName');
echo $xmlName;
echo "<br>";
$xmlValue = $xmlData->xpath('BsWfs:ParameterValue');
echo $xmlValue;
echo "<br>";
$query = "INSERT INTO Kaavio(ID,Päivämäärä,Parametri,Arvo) VALUES ('" . $xmlID . "','" . $xmlDate . "','" . $xmlName . "','" . $xmlValue . "')";
$result = mysqli_query($link, $query);
}
?>
现在我使用“xpath”,因为据我了解(到目前为止我所学到的)是,如果我使用 SimpleXML 选项,它不喜欢具有“前缀”的数据。这个 XML 数据在每个元素上都包含一些“前缀”标签。这就是为什么我使用“registerXPathNamespace”功能,但还没有解决我的问题。
如果您想知道我为什么使用以下代码,是因为我所有的图像格式都是这样的:@AnsaID-20@2020-05-31@19:55:36@.jpg :)
ob_start();
print end(explode('@',$first_image,-2));
$first_image_date = ob_get_contents();
ob_end_clean();
提前感谢您的帮助!
Edit1(用于 XML 数据,即使有链接):
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:BsWfs="http://xml.fmi.fi/schema/wfs/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" timeStamp="2020-06-24T20:12:30Z" numberReturned="24" numberMatched="24" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://xml.fmi.fi/schema/wfs/2.0 http://xml.fmi.fi/schema/wfs/2.0/fmi_wfs_simplefeature.xsd">
<wfs:member>
<BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.1">
<BsWfs:Location>
<gml:Point gml:id="BsWfsElementP.1.1.1" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
<gml:pos>60.81401 23.49761 </gml:pos>
</gml:Point>
</BsWfs:Location>
<BsWfs:Time>2020-05-24T00:00:00Z</BsWfs:Time>
<BsWfs:ParameterName>tmin</BsWfs:ParameterName>
<BsWfs:ParameterValue>8.2</BsWfs:ParameterValue>
</BsWfs:BsWfsElement>
</wfs:member>
<wfs:member>
<BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.2">
<BsWfs:Location>
<gml:Point gml:id="BsWfsElementP.1.1.2" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
<gml:pos>60.81401 23.49761 </gml:pos>
</gml:Point>
</BsWfs:Location>
<BsWfs:Time>2020-05-24T00:00:00Z</BsWfs:Time>
<BsWfs:ParameterName>tday</BsWfs:ParameterName>
<BsWfs:ParameterValue>11.1</BsWfs:ParameterValue>
</BsWfs:BsWfsElement>
</wfs:member>
<wfs:member>
<BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.3">
<BsWfs:Location>
<gml:Point gml:id="BsWfsElementP.1.1.3" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
<gml:pos>60.81401 23.49761 </gml:pos>
</gml:Point>
</BsWfs:Location>
<BsWfs:Time>2020-05-24T00:00:00Z</BsWfs:Time>
<BsWfs:ParameterName>tmax</BsWfs:ParameterName>
<BsWfs:ParameterValue>14.3</BsWfs:ParameterValue>
</BsWfs:BsWfsElement>
</wfs:member>
Edit2(添加现在“部分工作”的代码,但存在 MySQL 问题)
<?php
$folder_location = "AarniAnsa/*/*/";
$jpg = glob("" . $folder_location . "*.jpg");
$first_image = reset($jpg);
$last_image = end($jpg);
ob_start();
print end(explode('@',$first_image,-2));
$first_image_date = ob_get_contents();
ob_end_clean();
ob_start();
print end(explode('@',$last_image,-2));
$last_image_date = ob_get_contents();
ob_end_clean();
define('DB_SERVER', '***');
define('DB_USERNAME', '***');
define('DB_PASSWORD', '***');
define('DB_NAME', '***');
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if($link === false) {
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// Alla oleva linkki antaa pelkästään meille tmin (Alin lämpötila), tday (Keskilämpötila) sekä tmax (Ylin lämpötila) arvot. Muita muuttujia emme tarvitse.
$url = 'http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::daily::simple&place=tammela&starttime='.$first_image_date.'T00:00:00Z&endtime='.$last_image_date.'T01:00:00Z¶meters=tmin,tday,tmax&';
$xml = simplexml_load_file($url);
$xmlID = 0;
$xml->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs/2.0');
$xml->registerXPathNamespace('BsWfs', 'http://xml.fmi.fi/schema/wfs/2.0');
foreach ($xml->xpath('//wfs:member/BsWfs:BsWfsElement') as $xmlData) {
$xmlID++;
echo $xmlID;
echo "<br>";
$xmlDate = (string)$xmlData->xpath('BsWfs:Time')[0];
echo $xmlDate;
echo "<br>";
$xmlName = (string)$xmlData->xpath('BsWfs:ParameterName')[0];
echo $xmlName;
echo "<br>";
$xmlValue = (string)$xmlData->xpath('BsWfs:ParameterValue')[0];
echo $xmlValue;
echo "<br>";
$sql = "INSERT INTO Kaavio(Päivämäärä, Parametri, Arvo) VALUES('$xmlDate', '$xmlName', '$xmlValue')";
mysqli_query($link, $sql) or die(mysqli_error($link));
}
?>
以下代码出现此错误,我已检查数据库设置是否 100% 正确,因此问题不存在于此,我还尝试将 php 变量替换为普通文本(例如 'testi' 或 'aarni' ),但也没有用。
1
2020-05-24T00:00:00Z
tmin
8.2
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '�ivämäärä, Parametri, Arvo) VALUES('2020-05-24T00:00:00Z', 'tmin...' at line 1
Edit3(修复了我之前遇到的所有问题并在此处添加了整个代码,因此将来如果有人遇到类似问题,他们可以复制/粘贴它)
<?php
$folder_location = "AarniAnsa/*/*/";
$jpg = glob("" . $folder_location . "*.jpg");
$first_image = reset($jpg);
$last_image = end($jpg);
ob_start();
print end(explode('@',$first_image,-2));
$first_image_date = ob_get_contents();
ob_end_clean();
ob_start();
print end(explode('@',$last_image,-2));
$last_image_date = ob_get_contents();
ob_end_clean();
define('DB_SERVER', '***');
define('DB_USERNAME', '***');
define('DB_PASSWORD', '***');
define('DB_NAME', '***');
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if($link === false) {
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// Alla oleva linkki antaa pelkästään meille tmin (Alin lämpötila), tday (Keskilämpötila) sekä tmax (Ylin lämpötila) arvot. Muita muuttujia emme tarvitse.
$url = 'http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::daily::simple&place=tammela&starttime='.$first_image_date.'T00:00:00Z&endtime='.$last_image_date.'T01:00:00Z¶meters=tmin,tday,tmax&';
$xml = simplexml_load_file($url);
$xml->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs/2.0');
$xml->registerXPathNamespace('BsWfs', 'http://xml.fmi.fi/schema/wfs/2.0');
foreach ($xml->xpath('//wfs:member/BsWfs:BsWfsElement') as $xmlData) {
$xmlDate = (string)$xmlData->xpath('BsWfs:Time')[0];
$xmlDate = substr($xmlDate,0,10);
echo $xmlDate;
echo "<br>";
$xmlName = (string)$xmlData->xpath('BsWfs:ParameterName')[0];
echo $xmlName;
echo "<br>";
$xmlValue = (string)$xmlData->xpath('BsWfs:ParameterValue')[0];
echo $xmlValue;
echo "<br>";
$sql = "INSERT INTO `Kaavio` (`date`, `parameter`, `value`) VALUES('$xmlDate', '$xmlName', '$xmlValue')";
$result = mysqli_query($link, $sql);
}
?>
现在,当我打开 .php 脚本时,我的数组的外观/显示方式:
2020-05-24
tmin
8.2
2020-05-24
tday
11.1
2020-05-24
tmax
14.3
2020-05-25
tmin
8.0
2020-05-25
tday
13.0
2020-05-25
tmax
18.2
2020-05-26
tmin
4.6
2020-05-26
tday
14.9
这就是我的 phpMyAdmin 的外观(使用 MariaDB):
【问题讨论】:
-
SimpleXML 没有命名空间(前缀)的问题,更多的是人们不了解如何使用它们。看看stackoverflow.com/questions/12865858/… 看看这是否有帮助。如果没有,您能否添加一些示例 XML,我相信有人会给出更具体的答案。
-
您好,谢谢您的回答。我会检查一下并编辑我的 XML 数据帖子。
-
获取单个值的代码会给您数组到字符串转换错误,因为
xpath()总是返回一个元素列表。这些也将是 SimpleXMLElements,因此应转换为字符串以确保它们不会导致进一步的问题。所以像(string)$xmlData->xpath('BsWfs:Time')[0]这样的东西应该会给你结果。顺便说一句,即使有链接 - 不是每个人都想访问发布到 SO 的链接,将来这些链接可能会停止工作,因此问题中需要示例数据。 -
谢谢你的回答,我今天试试。不想对我的“编辑帖子”无礼。
-
抱歉@NigelRen 回复晚了,现在可以(部分)获取值,但下一个问题(我怀疑会发生)是我无法将这些值传输到我的数据库.出现以下错误(检查我的帖子,要编辑)
标签: php mysql xml xpath opendata