iOS 无法解析从服务器下载的 KML/XML
iOS cannot parse KML / XML downloaded from server
我包含在项目中的 KML 文件可以正确解析,而从服务器下载的同一文件却不能正确解析?!
我修改了 Apple's KML parsing example 以解析 KML 文件。如果我将 KML 文件直接添加到 Xcode 项目中,它会正确解析并按预期在地图上显示它的折线、注释等。但是,如果我从我的服务器下载相同的 KML 文件,将其保存到磁盘并尝试解析它,则解析不起作用。即解析器在文件中找不到要解析的任何元素,因此地图上没有显示任何内容!
首先,我已验证文件已正确下载并保存到磁盘。我检查了模拟器的数据(SimPholders 是一个方便的工具)来获取文件并将其与原始文件进行比较以防损坏,没有问题,它下载和保存正确,没有损坏。
接下来我检查了 URL 到我传递给 KML 解析器的文件,以确保它是正确的并且没问题。我使用 NSFileManager fileExistsAtPath 来确定这一点,KML 文件位于我提供给解析器的路径中。
在地图视图控制器的 viewDidLoad 方法中,我从服务器下载文件并将其传递给解析器。
- (void)viewDidLoad
{
[super viewDidLoad];
[[KmlDownloader sharedKmlDownloader] downloadFileFrom:@"http://www.myserver.com/file.kml" isAsyncDownload:NO];
NSURL *kmlUrl = [[KmlDownloader sharedKmlDownloader] urlForKmlFile];
if (kmlUrl)
{
kmlParser = [[KMLParser alloc] initWithURL:kmlUrl];
[kmlParser parseKML];
}
// Add all of the MKOverlay objects parsed from the KML file to the map.
NSArray *overlays = [kmlParser overlays];
[map addOverlays:overlays];
// Add all of the MKAnnotation objects parsed from the KML file to the map.
NSArray *annotations = [kmlParser points];
[map addAnnotations:annotations];
// Some positioning code of the view port here
}
作为参考的 KmlDownloader 可以作为 Gist here 找到。抱歉,格式太乱了,无法包含内联,但它是一个相对较小的文件。
知道为什么会这样吗?非常感谢。
好的,找到问题了。这与我在下载后访问文件的方式有关。保存到磁盘后,我会将其 URL 发送到解析器。问题是我使用了不正确的 NSURL 方法,我最初使用的是:
NSURL *fileUrl = [NSURL URLWithString:[self pathForFile:self.pathToKmlFileOnDisk]];
而我本应使用:
NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:self.pathToKmlFileOnDisk];
两者相同 URL 但第二个包含 "file:///"
前缀。一旦更改,解析器将按预期进行解析。
我包含在项目中的 KML 文件可以正确解析,而从服务器下载的同一文件却不能正确解析?!
我修改了 Apple's KML parsing example 以解析 KML 文件。如果我将 KML 文件直接添加到 Xcode 项目中,它会正确解析并按预期在地图上显示它的折线、注释等。但是,如果我从我的服务器下载相同的 KML 文件,将其保存到磁盘并尝试解析它,则解析不起作用。即解析器在文件中找不到要解析的任何元素,因此地图上没有显示任何内容!
首先,我已验证文件已正确下载并保存到磁盘。我检查了模拟器的数据(SimPholders 是一个方便的工具)来获取文件并将其与原始文件进行比较以防损坏,没有问题,它下载和保存正确,没有损坏。
接下来我检查了 URL 到我传递给 KML 解析器的文件,以确保它是正确的并且没问题。我使用 NSFileManager fileExistsAtPath 来确定这一点,KML 文件位于我提供给解析器的路径中。
在地图视图控制器的 viewDidLoad 方法中,我从服务器下载文件并将其传递给解析器。
- (void)viewDidLoad
{
[super viewDidLoad];
[[KmlDownloader sharedKmlDownloader] downloadFileFrom:@"http://www.myserver.com/file.kml" isAsyncDownload:NO];
NSURL *kmlUrl = [[KmlDownloader sharedKmlDownloader] urlForKmlFile];
if (kmlUrl)
{
kmlParser = [[KMLParser alloc] initWithURL:kmlUrl];
[kmlParser parseKML];
}
// Add all of the MKOverlay objects parsed from the KML file to the map.
NSArray *overlays = [kmlParser overlays];
[map addOverlays:overlays];
// Add all of the MKAnnotation objects parsed from the KML file to the map.
NSArray *annotations = [kmlParser points];
[map addAnnotations:annotations];
// Some positioning code of the view port here
}
作为参考的 KmlDownloader 可以作为 Gist here 找到。抱歉,格式太乱了,无法包含内联,但它是一个相对较小的文件。
知道为什么会这样吗?非常感谢。
好的,找到问题了。这与我在下载后访问文件的方式有关。保存到磁盘后,我会将其 URL 发送到解析器。问题是我使用了不正确的 NSURL 方法,我最初使用的是:
NSURL *fileUrl = [NSURL URLWithString:[self pathForFile:self.pathToKmlFileOnDisk]];
而我本应使用:
NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:self.pathToKmlFileOnDisk];
两者相同 URL 但第二个包含 "file:///"
前缀。一旦更改,解析器将按预期进行解析。