如何使用 XDocument 添加 xml 前缀?

Posted

技术标签:

【中文标题】如何使用 XDocument 添加 xml 前缀?【英文标题】:How to add xml prefix using XDocument? 【发布时间】:2018-12-14 11:24:27 【问题描述】:

如何使用 XDocument 将 xml 前缀添加到现有根元素? 我有以下 XML:

<processSalesOrder>
  <header/>
</processSalesOrder>

我希望它看起来像:

<ns0:processSalesOrder xmlns:ns0='https://xyx/'>
  <header/>
</ns0:processSalesOrder>

在我的场景中,我从 web api 接收这个 xml 并将其长时间传递给另一个 web 服务。 Web 服务需要根元素上的命名空间前缀。

Web 服务来自第三方软件,它需要某种格式的 xml。我尝试了 XmlDocument、XDocument 等……我找不到仅在根元素上添加命名空间前缀的方法。如果前缀在 Descendants 上,Webservice 将拒绝交易。

【问题讨论】:

docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… 看来这里可能有一些帮助:social.msdn.microsoft.com/Forums/en-US/… @Dijkgraaf 不要打扰,你无法让他们理解这一点。 嗨@satish,不幸的是,没有一个答案适用,因为它被错误地关闭为重复,你已经走到了死胡同。答案是 BizTalk 特定的,因此不是重复的。您将在 MSDN 的 BizTalk 论坛上获得更好的运气。 @Dijkgraaf 不值得。如果您未来的答案是 100% 正确、准确且第一次达到他们的标准,这就像 10 年禁令。 【参考方案1】:

Got Reference from here 开发者姓名:Vijay Sirigiri

如果您在加载 xml 文档后尝试为元素添加命名空间,那么这是不可能的。

来自 MSDN:

您不能添加、修改或删除 中的 XML 命名空间定义 之后的 XML 文档实例 文档已加载到 XML 文档对象模型 (XMLDOM) 解析器。 XML 节点用于 表示 XML 文档中的数据是 加载文档时创建 进入 XMLDOM 解析器。这些节点 永久绑定到它们的 XML 命名空间属性 创建的。因此,空 XML 命名空间声明 (xmlns = "") 是 附加到这些的子节点 节点以保留默认 XML 这些节点的命名空间属性。

但是,您可以加载输入、读取每个元素并将其写入具有命名空间集的另一个文档(或内存中)。 下面是解析字符串 xml,创建一个新的 xml 元素以及命名空间前缀和命名空间的代码。

            String xmlWithoutNamespace =
                @"<Folio><Node1>Value1</Node1><Node2>Value2</Node2><Node3>Value3</Node3></Folio>";
            String prefix ="vs";
            String testNamespace = "http://www.testnamespace/vs/";
            XmlDocument xmlDocument = new XmlDocument();

            XElement folio = XElement.Parse(xmlWithoutNamespace);
            XmlElement folioNode = xmlDocument.CreateElement(prefix, folio.Name.LocalName, testNamespace);

            var nodes = from node in folio.Elements()
                        select node;

            foreach (XElement item in nodes)
            
                var node = xmlDocument.CreateElement(prefix, item.Name.ToString(), testNamespace);
                node.InnerText = item.Value;
                folioNode.AppendChild(node);
            

            xmlDocument.AppendChild(folioNode);

xmlDocument 现在包含每个节点以 vs. 为前缀的 xml。

【讨论】:

当他试图在 BizTalk 中执行此操作时,我建议不要在这样的自定义代码中执行此操作,因为它可以使用开箱即用的 BizTalk 功能来完成。尝试在自定义代码中执行此操作可能会遇到线程问题(如 BizTalk 多线程)和内存使用问题(因为上面会将整个 XML 文档加载到内存中)。 哦。 @Dijkgraff【参考方案2】:

您正在尝试为空命名空间指定别名。 XDocument 不允许这样做:

前缀“ns0”不能绑定到空的命名空间名称。

所以不,我认为你不能用 XDocument 做到这一点。我认为这样做甚至不是有效的 XML - 强调我的:

[Definition:] 如果属性名称与 PrefixedAttName 匹配,则 NCName 给出名称空间前缀,用于将元素和属性名称与附加声明的元素范围内的属性值中的名称空间名称相关联。 在此类声明中,命名空间名称不得为空。

[Definition:] 如果属性名称与 DefaultAttName 匹配,则属性值中的名称空间名称是附加声明的元素范围内的默认名称空间名称。 在这样的默认声明中,属性值可能为空。默认命名空间和声明的覆盖在“5. 将命名空间应用于元素和属性”中讨论。

【讨论】:

我在示例中将其留空,但 Web 服务需要一个有效的命名空间。我现在不在工作,但是您认为我可以加载到新的内存流中并使用 xml 序列化添加带有命名空间的前缀吗? @satish but the webservice is expecting a valid namespace 为什么不相应地修改您的网络服务,而不是对 xml 进行一些修改。好像是XY prbplem 我无法在网络服务中进行修改,它来自第三方。 @satish 好像还是XY Problem你的实际问题还不清楚。 再次阅读帖子,如果它似乎是一个 XY 问题。请忽略该帖子。【参考方案3】:

根据 Roberts 的评论,您可以使用添加命名空间管道组件在接收管道中添加命名空间。如果您有 BizTalk Enterprise 并安装了 ESB 工具包,则有一个开箱即用的工具包,称为 ESB 添加命名空间,或者您必须编写自己的管道组件来执行此操作。

另一种选择是拥有两个架构,一个没有您在接收管道的 XML 反汇编器组件中指定的命名空间,另一个架构具有命名空间,并且您有一个从一个到另一个的映射。如果您不希望元素上的命名空间前缀,则第二个模式应将 ElementFormDefault 设置为(默认)或 Unqualified。如果您在未来对其进行验证,您还将拥有一个规范/内部架构,并从源架构映射到接收端口上的内部架构,以及从内部架构映射到发送端口上的目标架构。

【讨论】:

以上是关于如何使用 XDocument 添加 xml 前缀?的主要内容,如果未能解决你的问题,请参考以下文章

VB.NET:使用 XDocument 在 XML 文件中添加/编辑/删除 XElement

如何使用 C# XDocument 读取 xml 文件?

如何从 XDocument 获取 XML 节点

当数据集WriteXml()函数生成xml文件时,C#如何使用XDocument类更新xml文件

如何从 XDocument 获取 Xml 作为字符串?

将 xml 命名空间添加到 XDocument