转换 GML(Geography Markup Language)文件看起来很简单,直到读取器找不到 XML 架构为止。一个 GML 文件在单独的 XSD 中描述其要素类型和属性,并通过 schemaLocation 属性进行引用。当该架构丢失、移动或无法下载时,属性定义也随之丢失,原本在本机上能够运行的转换任务在构建服务器上就会失败。本指南展示了如何在 C# 中使用 Aspose.GIS for .NET 在转换过程中保留 GML 架构信息,以及如何验证要素和属性在往返转换后仍然存在。
为什么保留 GML 架构很重要
GML 是一种流行的交换格式,因为它将几何和属性数据一起携带。该数据的结构,即要素类型、属性名称和数据类型,由应用程序模式定义。Aspose.GIS 读取此模式以构建图层的属性集合,因此模式将原始 XML 转换为代码、QGIS 或 ArcGIS 中可用的列。
在实际的流水线中,模式通常是最薄弱的环节。文件在复制时没有随带 XSD,schemaLocation 指向了过时的 URL,或者运行转换的服务器没有互联网访问权限。在这些情况下,Aspose.GIS 会抛出 GisException,说明它未能构建要素属性集合。GmlOptions.RestoreSchema 选项通过允许读取器从要素数据本身重建属性模式来解决此问题,从而使您的转换保留属性,而不是失败或产生不完整的输出。
开始使用 Aspose.GIS for .NET
Aspose.GIS for .NET 是一个托管库,用于读取、写入和转换 GIS 格式,如 GML、Shapefile、GeoJSON、KML 和 File Geodatabase,无需在机器上安装 ArcGIS 或 QGIS。可通过 NuGet 将其添加到项目中:
Install-Package Aspose.GIS
或者使用 .NET CLI:
dotnet add package Aspise.GIS
您可以在 Aspose.GIS for .NET 产品页面以及 Aspose.GIS .NET API Reference 中了解更多信息。本教程中使用的两个命名空间是 Aspose.Gis,其中包含 VectorLayer、Drivers 和 ConversionOptions,以及 Aspose.Gis.Formats.Gml,其中包含 GmlOptions。
逐步教程:保留 GML 架构
以下 C# 示例将 GML 文件转换为新的 GML 文件,同时恢复属性模式,然后验证结果。它针对 .NET 6 或更高版本。
示例的作用
- 使用
GmlOptions.RestoreSchema设置为true创建读取器选项。 - 打开源 GML 并记录其要素计数和属性名称。
- 使用
VectorLayer.Convert转换文件,通过ConversionOptions.SourceDriverOptions传递读取器选项。 - 重新打开输出并恢复模式,然后将其与源进行比较。
using System;
using System.IO;
using System.Linq;
using Aspose.Gis;
using Aspose.Gis.Formats.Gml;
class PreserveGmlSchema
{
static void Main()
{
// Input and output paths. Adjust them to your environment.
string sourcePath = Path.Combine("data", "input.gml");
string destinationPath = Path.Combine("data", "output.gml");
// Step 1: Capture the structure of the source layer.
// RestoreSchema lets the reader infer attributes when the XSD is missing or unreachable.
int sourceFeatureCount;
string[] sourceAttributeNames;
using (VectorLayer source = VectorLayer.Open(sourcePath, Drivers.Gml, CreateReadOptions()))
{
sourceFeatureCount = source.Count;
sourceAttributeNames = source.Attributes.Select(a => a.Name).ToArray();
}
// Step 2: Convert GML to GML. RestoreSchema is a reader option,
// so it is supplied through SourceDriverOptions.
var conversionOptions = new ConversionOptions
{
SourceDriverOptions = CreateReadOptions()
};
VectorLayer.Convert(sourcePath, Drivers.Gml, destinationPath, Drivers.Gml, conversionOptions);
// Step 3: Reopen the output and compare it with the source.
using (VectorLayer output = VectorLayer.Open(destinationPath, Drivers.Gml, CreateReadOptions()))
{
if (output.Count != sourceFeatureCount)
{
throw new InvalidOperationException(
$"Feature count mismatch: source has {sourceFeatureCount}, output has {output.Count}.");
}
string[] outputAttributeNames = output.Attributes.Select(a => a.Name).ToArray();
string[] missingAttributes = sourceAttributeNames.Except(outputAttributeNames).ToArray();
if (missingAttributes.Length > 0)
{
throw new InvalidOperationException(
$"Attributes missing from output: {string.Join(", ", missingAttributes)}");
}
Console.WriteLine($"Converted {output.Count} features with {output.Attributes.Count} attributes:");
foreach (FeatureAttribute attribute in output.Attributes)
{
Console.WriteLine($" {attribute.Name} ({attribute.DataType})");
}
}
}
// A fresh options instance for each read keeps the configuration explicit.
static GmlOptions CreateReadOptions() => new GmlOptions { RestoreSchema = true };
}
每个步骤的解释
- 创建读取器选项 –
GmlOptions保存 GML 特定的驱动程序设置。根据 GmlOptions.RestoreSchema 文档,将其设置为true表示读取器不再需要 XML 架构。驱动程序会扫描文件中的已知 GML 结构并推断要素类及其属性。默认值为false。 - 捕获源结构 – 使用
VectorLayer.Open打开源文件可获得基准。layer.Count返回要素数量,layer.Attributes暴露属性集合,其中每个FeatureAttribute都有Name和DataType。 - 调用
VectorLayer.Convert– 此处使用的重载接受源路径、源驱动、目标路径、目标驱动以及一个ConversionOptions对象。SourceDriverOptions控制输入的读取方式,DestinationDriverOptions控制输出的写入方式。由于RestoreSchema影响读取,它应放在源端。 - 验证输出 – 使用相同的读取器选项重新打开输出,以便验证不依赖于 XSD。示例不是使用硬编码的数字,而是将输出与源进行比较。当要素或属性丢失时会失败,并打印恢复后的属性名称和数据类型供检查。额外的属性不视为错误,因为诸如
gml_id的标识符在转换后可能以不同方式呈现。
读取 GML(原始 XSD 可用时)
模式恢复是一种回退方案。如果仍然拥有原始模式文件,请使用 SchemaLocation 将读取器指向该文件,以便属性定义来自 XSD 而不是被推断出来:
using System;
using Aspose.Gis;
using Aspose.Gis.Formats.Gml;
var options = new GmlOptions
{
// Space-separated pair: namespace URI, then the path to its XML schema.
SchemaLocation = "http://www.example.com/myfeatures schema.xsd",
LoadSchemasFromInternet = false
};
using (VectorLayer layer = VectorLayer.Open("input.gml", Drivers.Gml, options))
{
Console.WriteLine($"Features: {layer.Count}, attributes: {layer.Attributes.Count}");
}
当 SchemaLocation 为 null(默认值)时,Aspose.GIS 会从 GML 文档的根元素读取 schemaLocation。LoadSchemasFromInternet 默认是 false,因此除非启用,否则不会下载通过绝对非 file:// URI 引用的模式。
获取免费许可证
Aspose.GIS 在评估模式下运行,具有一定限制,直至应用许可证。要测试完整功能集,请请求 免费临时许可证 并在首次 GIS 操作之前应用它:
var license = new Aspose.Gis.License();
license.SetLicense("Aspose.GIS.NET.lic");
免费额外资源
结论
在转换过程中保留 GML 架构信息的关键在于控制源的读取方式。通过在 ConversionOptions.SourceDriverOptions 中传递 GmlOptions.RestoreSchema,Aspose.GIS for .NET 即使在 XSD 缺失或不可访问的情况下也能重建属性定义,从而使转换保持数据而不是失败。将此选项与源到输出的比较相结合,可提供特征和属性已成功传递的证据;当原始架构可用时切换到 SchemaLocation 则可获得最忠实的结果。这些做法共同确保 GML 转换在批处理作业、Web 服务和 CI 流水线中可靠运行。
常见问题
1. GmlOptions.RestoreSchema 实际上是做什么的?
它允许 Aspose.GIS GML 阅读器在文件引用的 XML 架构 (XSD) 缺失或无法加载时解析要素属性。驱动程序会扫描文档中的已知 GML 结构,并根据数据推断要素类及其属性。默认值为 false.
2. 是否需要在转换和输出文件上都设置 RestoreSchema?
仅针对无法加载模式的文件。 RestoreSchema 是读取器选项,因而在转换期间它应放在 ConversionOptions.SourceDriverOptions 中,而在重新打开输出时则将其传递给 VectorLayer.Open。 示例在两个位置都设置了它,以便工作流不依赖于可用的 XSD。
3. 如果 RestoreSchema 为 false 且模式缺失,会发生什么?
Aspose.GIS 无法构建要素属性集合并抛出 GisException。异常消息建议将 RestoreSchema 设置为 true,或在模式托管在线时将 LoadSchemasFromInternet 设置为 true。
4. 恢复的模式是否与原始 XSD 完全相同?
不一定。Aspose.GIS 将模式恢复描述为容易出错,因为属性是通过扫描文件推断的。请像示例那样验证结果,并在拥有原始 XSD 时使用 GmlOptions.SchemaLocation。
5. 在将 GML 转换为 Shapefile、GeoJSON 或其他格式时,我可以使用 RestoreSchema 吗?
是的。SourceDriverOptions 控制 GML 源的读取方式,且不受目标驱动程序的影响。恢复的属性随后使用目标格式自己的属性模型进行写入。
6. 我需要许可证来运行此代码吗? 不需要。没有许可证,Aspose.GIS 以评估模式运行,存在限制。免费临时许可证可消除这些限制以进行测试,生产使用则需要购买许可证。
