將 GML(Geography Markup Language)檔案轉換看似簡單,直到讀取器找不到 XML 架構。A GML 檔案在一個單獨的 XSD 中描述其要素類型和屬性,該 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 Aspose.GIS

您可以在 Aspose.GIS for .NET 產品頁面以及 Aspose.GIS .NET API 參考手冊 上了解更多資訊。本教學中使用的兩個命名空間分別是 Aspose.Gis(其中包含 VectorLayer、Drivers 和 ConversionOptions)以及 Aspose.Gis.Formats.Gml(其中包含 GmlOptions)。

逐步教學:保留 GML 架構

以下 C# 範例將 GML 檔案轉換為新的 GML 檔案,同時還原屬性結構,然後驗證結果。它的目標是 .NET 6 或更高版本。

範例的功能

  1. 使用 GmlOptions.RestoreSchema 設為 true 來建立讀取器選項。
  2. 開啟來源 GML,並記錄其要素計數和屬性名稱。
  3. 使用 VectorLayer.Convert 轉換檔案,透過 ConversionOptions.SourceDriverOptions 傳遞讀取器選項。
  4. 重新開啟輸出,恢復結構,並將其與來源進行比較。
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 之類的識別碼在轉換後可能以不同方式顯示。

在原始 XSD 可用時讀取 GML

Schema restoration 是一種備援方案。如果您仍然擁有原始的 schema 檔案,請使用 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 架構資訊的關鍵在於控制來源的讀取方式。將 GmlOptions.RestoreSchema 透過 ConversionOptions.SourceDriverOptions 傳遞,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 以評估模式運行,並有一些限制。免費的臨時許可證可在測試時移除這些限制,而正式生產環境則需要購買許可證。

閱讀更多