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

如何通过创建未附加元素生成带命名空间的XDocument相关文档

构建带XNamespace的XDOM树时属性命名空间异常问题

我先创建XElement和XAttribute对象构建DOM树,之后再将其添加到XDocument中。但涉及XNamespace时出现了不符合预期的输出,以下是简化的测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace XamlTest
{
  internal class Program
  {
    private static readonly Dictionary<string, string> XamlNamespaces = new Dictionary<string, string>()
    {
      { "xmlns", "http://schemas.microsoft.com/winfx/2006/xaml/presentation" },
      { "xmlns:x", "http://schemas.microsoft.com/winfx/2006/xaml" }
    };

    private static readonly Dictionary<string, XNamespace> _ns = XamlNamespaces.Select(ns => new { 
        Key = ns.Key.StartsWith("xmlns:") ? ns.Key.Substring(6) : "", 
        Value = (XNamespace)ns.Value 
    }).ToDictionary(ns => ns.Key, ns => ns.Value);


    internal static void Main()
    {
      CreateDocument();
      Console.ReadKey();
    }

    public static void CreateDocument()
    {
      XElement root = new XElement(_ns[""] + "Section");

      foreach (KeyValuePair<string, XNamespace> ns in _ns)
        root.Add(new XAttribute(string.IsNullOrEmpty(ns.Key) ? "xmlns" : XNamespace.Xmlns + ns.Key, ns.Value));

      XDocument xamlDoc = new XDocument(root);
      root.Add(CreateTree());

      Console.WriteLine(xamlDoc.ToString());
    }


    private static List<XElement> CreateTree()
    {
      List<XElement> newElements = [];

      newElements.Add(new XElement(_ns[""] + "Paragraph",
                      new XAttribute(_ns[""] + "FontSize", "12")
                      ));

      return newElements;
    }
  }
}

当前执行结果

<Section xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Paragraph p3:FontSize="12" xmlns:p3="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
</Section>

预期输出

<Section xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Paragraph FontSize="12"/>
</Section>

问题分析与解决

原因

XAML的默认命名空间仅作用于元素,普通属性(如FontSize)不需要绑定命名空间。你给FontSize添加了默认命名空间后,LINQ to XML会将其识别为带命名空间的属性,而根节点的默认命名空间只对元素生效,因此会自动生成新的前缀(如p3)来标记这个属性,导致输出不符合预期。

修复方案

去掉FontSize属性的命名空间绑定,直接使用属性名创建XAttribute即可。修改后的CreateTree方法如下:

private static List<XElement> CreateTree()
{
  List<XElement> newElements = [];

  newElements.Add(new XElement(_ns[""] + "Paragraph",
                  new XAttribute("FontSize", "12")
                  ));

  return newElements;
}

验证结果

修改后执行代码,输出将符合预期:

<Section xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Paragraph FontSize="12" />
</Section>

额外优化

可以简化命名空间的初始化逻辑,让代码更易读:

private static readonly Dictionary<string, XNamespace> _ns = new()
{
    [""] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation",
    ["x"] = "http://schemas.microsoft.com/winfx/2006/xaml"
};

这样就不需要从原字典中截取键名,直接定义命名空间别名和对应的URI即可。


内容的提问来源于stack exchange,提问作者AxD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:55:07