具有不同本地名称的 XDocument 重复命名空间

2023-11-30

我有一个 XML 文档,如下所示:

    <Schema Namespace="BBSF_Model" Alias="Self"
      p1:UseStrongSpatialTypes="false"
      xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
      xmlns:p1="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
      xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
    <EntityType Name="Customer">
        <Property Name="Id" Type="Guid" Nullable="false" />
    </EntityType>
  </Schema>

我使用以下代码来修改文档的属性元素:

    XElement csdlEentity = csdlDoc.Root.Descendants()
            .Where(d => d.Name.LocalName == "EntityType")
            .FirstOrDefault(e => e.Attribute("Name").Value == "Customer");

    var csdlProperty = csdlEentity.Descendants()
            .Where(d => d.Name.LocalName == "Property")
            .FirstOrDefault(e => e.Attribute("Name").Value == "Id");

    XNamespace annotation = "http://schemas.microsoft.com/ado/2009/02/edm/annotation";
    var attrib = new XAttribute(annotation + "StoreGeneratedPattern", "Computed");
    csdlProperty.Add(attrib);

当我保存 XDocument 时,属性元素如下所示:

    <Property Name="Id" Type="Guid" Nullable="false" p1:StoreGeneratedPattern="Computed" />

然而我想要的是:

  <Property Name="Id" Type="Guid" Nullable="false" annotation:StoreGeneratedPattern="Computed" />

问题是 xmlns "http://schemas.microsoft.com/ado/2009/02/edm/annotation" 在文档的根节点中使用两个不同的别名/LocalNames 被引用两次(注释,p1)

    xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
    xmlns:p1="http://schemas.microsoft.com/ado/2009/02/edm/annotation"

我无法更改或篡改根节点。

如何保存文档或更新属性元素以提供所需的输出?


理论上,是否使用前缀并不重要p1:StoreGeneratedPattern="Computed" or annotation:StoreGeneratedPattern="Computed",因为这些意味着完全相同的事情-- 一个元素扩展的 XML 名称 of {http://schemas.microsoft.com/ado/2009/02/edm/annotation}StoreGeneratedPattern。如果您的接收 XML 解析器(或 QA 部门?)在处理此问题时遇到问题,最简单的修复可能是将解析器修复为符合标准.

话虽如此,从参考来源 for XElement,事实证明,名称空间/前缀属性对被推送到下推堆栈按照写入时的添加顺序,然后检查与元素名称空间的匹配从上到下堆栈的——有效地以与添加属性相反的顺序进行匹配。所以如果你想使用前缀annotation,您可以简单地排列根元素中重复名称空间的顺序。 (详细信息请参见here.)

但是,你写道,你无法更改或篡改根节点。因此,您将被迫做一些工作:您将需要创建自己的包装子类XmlWriter并自己重新映射前缀。

首先,一个非抽象子类XmlWriter包裹着一个“真实的”XmlWriter:

public class XmlWriterProxy : XmlWriter
{
    readonly XmlWriter baseWriter;

    public XmlWriterProxy(XmlWriter baseWriter)
    {
        if (baseWriter == null)
            throw new ArgumentNullException();
        this.baseWriter = baseWriter;
    }

    protected virtual bool IsSuspended { get { return false; } }

    public override void Close()
    {
        baseWriter.Close();
    }

    public override void Flush()
    {
        baseWriter.Flush();
    }

    public override string LookupPrefix(string ns)
    {
        return baseWriter.LookupPrefix(ns);
    }

    public override void WriteBase64(byte[] buffer, int index, int count)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteBase64(buffer, index, count);
    }

    public override void WriteCData(string text)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteCData(text);
    }

    public override void WriteCharEntity(char ch)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteCharEntity(ch);
    }

    public override void WriteChars(char[] buffer, int index, int count)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteChars(buffer, index, count);
    }

    public override void WriteComment(string text)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteComment(text);
    }

    public override void WriteDocType(string name, string pubid, string sysid, string subset)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteDocType(name, pubid, sysid, subset);
    }

    public override void WriteEndAttribute()
    {
        if (IsSuspended)
            return;
        baseWriter.WriteEndAttribute();
    }

    public override void WriteEndDocument()
    {
        if (IsSuspended)
            return;
        baseWriter.WriteEndDocument();
    }

    public override void WriteEndElement()
    {
        if (IsSuspended)
            return;
        baseWriter.WriteEndElement();
    }

    public override void WriteEntityRef(string name)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteEntityRef(name);
    }

    public override void WriteFullEndElement()
    {
        if (IsSuspended)
            return;
        baseWriter.WriteFullEndElement();
    }

    public override void WriteProcessingInstruction(string name, string text)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteProcessingInstruction(name, text);
    }

    public override void WriteRaw(string data)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteRaw(data);
    }

    public override void WriteRaw(char[] buffer, int index, int count)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteRaw(buffer, index, count);
    }

    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteStartAttribute(prefix, localName, ns);
    }

    public override void WriteStartDocument(bool standalone)
    {
        baseWriter.WriteStartDocument(standalone);
    }

    public override void WriteStartDocument()
    {
        baseWriter.WriteStartDocument();
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteStartElement(prefix, localName, ns);
    }

    public override WriteState WriteState
    {
        get { return baseWriter.WriteState; }
    }

    public override void WriteString(string text)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteString(text);
    }

    public override void WriteSurrogateCharEntity(char lowChar, char highChar)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteSurrogateCharEntity(lowChar, highChar);
    }

    public override void WriteWhitespace(string ws)
    {
        if (IsSuspended)
            return;
        baseWriter.WriteWhitespace(ws);
    }
}

接下来,允许重新映射属性名称空间前缀的子类:

public class PrefixSelectingXmlWriterProxy : XmlWriterProxy
{
    readonly Stack<XName> elements = new Stack<XName>();
    readonly Func<string, string, string, Stack<XName>, string> attributePrefixMap;

    public PrefixSelectingXmlWriterProxy(XmlWriter baseWriter, Func<string, string, string, Stack<XName>, string> attributePrefixMap)
        : base(baseWriter)
    {
        if (attributePrefixMap == null)
            throw new NullReferenceException();
        this.attributePrefixMap = attributePrefixMap;
    }

    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        prefix = attributePrefixMap(prefix, localName, ns, elements);
        base.WriteStartAttribute(prefix, localName, ns);
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement(prefix, localName, ns);
        elements.Push(XName.Get(localName, ns));
    }

    public override void WriteEndElement()
    {
        base.WriteEndElement();
        elements.Pop(); // Pop after base.WriteEndElement() lets the base class throw an exception on a stack error.
    }
}

最后你会像这样使用它:

        string xml;
        using (var sw = new StringWriter())
        {
            using (var xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, IndentChars = "  " }))
            using (var xmlWriterProxy = new PrefixSelectingXmlWriterProxy(xmlWriter,
                (string prefix, string localName, string ns, Stack<XName> parents) =>
                {
                    if (localName == "StoreGeneratedPattern" && ns == annotation && parents.Peek() == XName.Get("Property", "http://schemas.microsoft.com/ado/2009/11/edm"))
                        return "annotation";
                    return prefix;
                })
                )
            {
                csdlDoc.WriteTo(xmlWriterProxy);
            }
            xml = sw.ToString();
        }
        Debug.WriteLine(xml);

正如您所看到的,这仅重新映射属性前缀,但它显然可以通过覆盖来扩展以重新映射元素前缀WriteStartElement(string prefix, string localName, string ns).

Working fiddle.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有不同本地名称的 XDocument 重复命名空间 的相关文章

  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 扩展 XSD 文件

    我有一个带有枚举类型的 XSD 文件 我想创建一个 扩展 XSD 文件 它添加一些额外的枚举 但其他方面的行为就像主 XSD 一样 例如 主 XSD 文件包含以下内容
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 按钮 - 单击时更改背景颜色

    我的活动中有 8 个按钮 我正在寻找的是 按钮具有默认背景 单击按钮时 背景颜色应更改为其他颜色 这部分非常简单 但是 当我单击任何其他按钮时 第一个按钮的背景颜色应该变回默认颜色 我知道这将使用 选择器状态 来完成 但我不太确定如何实现它
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐

  • C++ 类成员初始化顺序

    我知道在一个class成员按照列出的顺序进行初始化 这是否适用于将变量分组为public and privateETC 我的困惑是我无法弄清楚是否存在诸如private成员按照之前列出的顺序进行初始化public成员 无论私有变量在类声明中
  • Deadline_timers 的非阻塞 boost io_service

    阅读 boost asio deadline timer 的文档后 似乎 io service run 和处理程序方法是在同一线程上调用的 在后台线程上运行 io service 对象时 是否有任何方法可以在一个线程上创建计时器 为了好玩和
  • 拉链常见问题

    给定任何容器类型 我们都可以形成 以元素为中心的 Zipper 并且知道该结构是 Comonad 最近对此进行了精彩的详细探讨另一个堆栈溢出问题对于以下类型 data Bin a Branch Bin a a Bin a Leaf a de
  • 通过 FetchContent 安装 protobuf 时如何使用 cmake 命令 protobuf_generate?

    我正在使用 gRPC 编写客户端 服务器 要生成客户端 服务器 protobuf 代码 我需要运行 cmake 命令protobuf generate 如果我事先安装了 protobuf 我就可以访问该命令protobuf generate
  • Silverlight 4 和 Windows Phone 7 的 Bing 地图控件中的交互式图层

    使用 Bing 地图控件时 我的应用程序会添加一个叠加层 在其上将位置标记绘制为椭圆形 每个椭圆都连接到一个 Tap 处理程序 该处理程序在 WP7 模拟器中按预期工作 遗憾的是 HTC 硬件上的情况似乎并非如此 地图本身似乎获取了所有输入
  • 如何将 PHP 字符串传递到 Javascript 函数调用中? [复制]

    这个问题在这里已经有答案了 可能的重复 将 PHP 字符串传递给 Javascript 变量 并转义换行符 所以 本质上我试图从 PHP 页面传递一个字符串作为 javascript 函数的参数 PHP 包含在脚本所在的页面中 但它们位于两
  • 带有行号的 pandas 堆栈

    我有一个 Pandas DataFrame 示例 A B C D 0 0 441040 0 235533 0 899417 1 960367 1 0 701764 2 343389 1 293865 0 556737 2 0 511988
  • 何时使用 L.TileLayer 与 L.tileLayer

    我刚刚使用 Leaflet 为网站构建地图 并注意到要添加平铺层至少可以使用两种方法 L TileLayer and L tileLayer 其名称仅因单个字符的大小写而异 然而 虽然这两种方法返回的对象都可以添加到由L map 返回的对象
  • PHP - CodeIgniter - 为 foreach() 提供的参数无效

    我尝试使用 CodeIgniter 编写一个网站 但 PHP 遇到问题 我确信它是如此简单并且不会错 但我不知道 bug 只是 CodeIgniter 的新手
  • Spring异常时事务回滚

    我正在学习Spring 并且在Spring中的事务处理方面遇到了一些麻烦 这是我的代码 Transactional rollbackFor Exception class public void createGroupStudent Stu
  • 如何使用 purrr map 函数执行逐行 prop.tests 并将结果添加到数据帧?

    我正在尝试解决 R 中的以下问题 我有一个包含两个变量 成功次数和总试验次数 的数据框 A tibble 4 x 2 Success N
  • 如何将国家/地区拨号代码放入 intlTelInput 中的括号中

    我在我的网站上使用 intlTelInput 如何使用括号分隔拨号代码 对于前 这个插件的默认输出是 1202someNumber 我需要 1 202someNum 基于此处的文档表格 https github com jackocnr i
  • Pandas Dataframe 到带分隔符的字符串

    我想将数据框转换为字符串 这个话题如何将 pandas 数据框行转换为逗号分隔的字符串接近我想要的 此解决方案的唯一问题 我有一列 国家 其中包含带有分隔符的字符串 例如 使用此解决方案 数据框正在转换为字符串 但我将 美国 变为 美国 州
  • OpenCV Android 原生代码构建问题

    我正在学习如何使用 OpenCV 编写 C 代码 我想在 Android 中运行它 我使用Android Studio 我创建了一个支持 C 的新简单项目 然后将测试代码添加到 C 文件中 看来是我自己的文件编译和链接的 现在 我认为与我的
  • 确定数据表中的重复项

    我有一个从 CSV 文件加载的数据表 我需要根据两列确定哪些行是重复的 product id and owner org id 在数据表中 一旦确定了这一点 我就可以使用该信息来构建结果 该结果是一个仅包含不唯一行的数据表 以及一个仅包含唯
  • 只需按一下按键即可连续移动?

    我正在尝试用java编写一个程序 该程序涉及通过按一次按键使对象不断移动 想想 Pacman 你按下一次 Pacman 就会继续上升 直到你按下另一个键 如果可能的话 我想让代码保持简单 我原来的动作 一次按键 一次动作 是这样的 publ
  • 将类变量传递给另一个类

    我想将一个类变量传递给另一个类 并使其成为该类的类变量 在以下情况下我将如何执行此操作 public class GLCamTest extends Activity public float array something class G
  • Jena Fuseki Sparql 无查询=错误

    我正在尝试使用这个简单的查询将数据插入 jena fusioni 图中 PREFIX test
  • Android 语音通话记录

    我希望有一些代码能够收到任何传入和传出语音呼叫的通知 我需要获取以下所有内容 如果是来电或去电 拨打的号码或来电显示的电话号码 通话时长 或者是否是未接来电 如果我可以获得更多联系信息 特别是联系人姓名 如果电话号码与手机联系人列表中的某个
  • 具有不同本地名称的 XDocument 重复命名空间

    我有一个 XML 文档 如下所示