You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中缓存含Include/Import的XSD进行XML验证的实现问题

Fixing XSD Caching with Include/Import for XML Validation Performance

I’ve run into this exact issue before—getting XSD includes/imports to play nice with a cached XmlSchemaSet can be tricky, but once you nail it, the performance boost is huge. Here’s how to resolve the problem and get your cached schemas working reliably:

Why Your Current Setup Isn’t Working

When you add just the main XSD to XmlSchemaSet, it won’t automatically resolve included/imported schemas unless you configure a resolver or explicitly add dependencies. The compiler throws errors because it can’t locate those dependent files during compilation, leaving your schema set incomplete and unusable for repeated validation.

Step-by-Step Solution to Cache a Complete XmlSchemaSet

1. Precompile the Schema Set with All Dependencies

You have two reliable approaches to ensure all schemas (including nested ones) are included in the cached set:

Approach A: Explicitly Add All Schemas

If you know the paths to every included/imported XSD, add them directly to the set before compiling. This guarantees all schemas are loaded and validated together.

// Cache this instance (use a static variable, singleton, or app-level cache)
private static XmlSchemaSet _cachedSchemaSet;

public static XmlSchemaSet GetCachedSchemaSet()
{
    if (_cachedSchemaSet == null)
    {
        _cachedSchemaSet = new XmlSchemaSet();
        
        // Add dependent schemas first (order may matter for cross-references)
        _cachedSchemaSet.Add(null, @"path/to/dependency1.xsd");
        _cachedSchemaSet.Add(null, @"path/to/dependency2.xsd");
        
        // Add the main schema last
        _cachedSchemaSet.Add(null, @"path/to/main.xsd");
        
        // Compile to validate all schemas and lock the set for reuse
        _cachedSchemaSet.Compile();
    }
    return _cachedSchemaSet;
}

Approach B: Use a Resolver to Auto-Resolve Includes/Imports

If your main XSD uses relative paths for includes/imports, configure an XmlReader with a resolver to let XmlSchemaSet find those files automatically.

private static XmlSchemaSet _cachedSchemaSet;

public static XmlSchemaSet GetCachedSchemaSet()
{
    if (_cachedSchemaSet == null)
    {
        _cachedSchemaSet = new XmlSchemaSet();
        
        // Set a resolver to handle relative paths (default is XmlUrlResolver)
        _cachedSchemaSet.XmlResolver = new XmlUrlResolver();
        
        // Load the main schema with a reader that knows the base path
        using (var reader = XmlReader.Create(@"path/to/main.xsd", new XmlReaderSettings { XmlResolver = _cachedSchemaSet.XmlResolver }))
        {
            _cachedSchemaSet.Add(null, reader);
        }
        
        // Compile to resolve and load all nested schemas
        _cachedSchemaSet.Compile();
    }
    return _cachedSchemaSet;
}

2. Reuse the Cached Schema Set for Validation

Once your schema set is compiled and cached, use it for every XML validation to avoid reloading schemas:

public bool ValidateXml(string xmlContent)
{
    var schemaSet = GetCachedSchemaSet();
    var settings = new XmlReaderSettings
    {
        Schemas = schemaSet,
        ValidationType = ValidationType.Schema,
        ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings
    };
    
    // Handle validation errors (customize this to your needs)
    settings.ValidationEventHandler += (sender, e) => 
    {
        if (e.Severity == XmlSeverityType.Error)
            throw new XmlSchemaValidationException($"Validation failed: {e.Message}");
    };
    
    // Read through the XML to trigger validation
    using (var reader = XmlReader.Create(new StringReader(xmlContent), settings))
    {
        while (reader.Read()) { }
    }
    return true;
}

Key Notes to Avoid Issues

  • Compile Once: Always call Compile() after adding all schemas—this ensures dependencies are resolved and the set is locked for safe reuse.
  • Cache Correctly: Store the compiled XmlSchemaSet in a static variable, singleton, or application-level cache (like MemoryCache) to avoid recreating it on every validation.
  • Permission Checks: Ensure your app has read access to all XSD files (including dependencies) when compiling the set.
  • Relative Paths: If using relative paths, verify the resolver’s base directory is correct—you can set the BaseUri property on the XmlReader or use a custom resolver for embedded resources.

Troubleshooting Tips

  • If you still get "cannot resolve schema" errors, enable verbose logging to identify missing schemas:
    settings.ValidationEventHandler += (sender, e) => 
    {
        Console.WriteLine($"Validation {e.Severity}: {e.Message}");
    };
    
  • Double-check that targetNamespace values in included/imported schemas match references in the main schema.
  • For embedded schemas, create a custom XmlResolver to load them directly from your assembly.

内容的提问来源于stack exchange,提问作者aeb-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:14:29