前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Modifying namespace in XML document programmatically

Modifying namespace in XML document programmatically

作者头像
阿新
发布于 2018-04-12 02:41:50
发布于 2018-04-12 02:41:50
1.4K00
代码可运行
举报
文章被收录于专栏:c#开发者c#开发者
运行总次数:0
代码可运行

Modifying namespace in XML document programmatically

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static XElement stripNS(XElement root) {
    return new XElement(
        root.Name.LocalName,
        root.HasElements ? 
            root.Elements().Select(el => stripNS(el)) :
            (object)root.Value
    );
}
static void Main() {
    var xml = XElement.Parse(@"<?xml version=""1.0"" encoding=""utf-16""?>
    <ArrayOfInserts xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
      <insert>
        <offer xmlns=""http://schema.peters.com/doc_353/1/Types"">0174587</offer>
        <type2 xmlns=""http://schema.peters.com/doc_353/1/Types"">014717</type2>
        <supplier xmlns=""http://schema.peters.com/doc_353/1/Types"">019172</supplier>
        <id_frame xmlns=""http://schema.peters.com/doc_353/1/Types"" />
        <type3 xmlns=""http://schema.peters.com/doc_353/1/Types"">
          <type2 />
          <main>false</main>
        </type3>
        <status xmlns=""http://schema.peters.com/doc_353/1/Types"">Some state</status>
      </insert>
    </ArrayOfInserts>");
    Console.WriteLine(stripNS(xml));
}

I needed to validate an XML document with a given XSD document. Seems easy enough… so let’s have a look at the schema first:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"           
                 xmlns="http://my.namespace"          
                 elementFormDefault="qualified"           
                 targetNamespace="http://my.namespace"> 
  <xs:element name="customer">   
    <xs:complexType>     
      <xs:sequence>       
      <xs:element name="firstname" type="xs:string" />       
      <xs:element name="lastname" type="xs:string" />       
      <xs:element name="age" type="xs:integer" />     
      </xs:sequence>   
    </xs:complexType> 
  </xs:element>
</xs:schema>

The XML instance is:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8" ?>
<customer>
  <firstname>Homer</firstname>
  <lastname></lastname>
  <age>36</age>
</customer> 

The code is straightforward:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void Main(string[] args)
{
  // Load the xml document
  XDocument source = XDocument.Load(@"instance.xml");
  // Load the schema
  XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
  xmlSchemaSet.Add(null, XmlReader.Create(@"customer.xsd"));
  // Validate
  try { source.Validate(xmlSchemaSet, ValidationCallback, true); }
  catch (Exception ex) { Console.WriteLine(ex.Message); }
}
static void ValidationCallback(object sender, 
    System.Xml.Schema.ValidationEventArgs e)
{
  Console.WriteLine(string.Format("[{0}] {1}", e.Severity, e.Message));
} 

If you run this, no errors are thrown so it seems to validate. To be sure, let’s change the age in an invalid value:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Age>invalid!</Age>

and test again. Well… actually, no validation error is thrown in this case either… what’s going on here?

Actually, the XML is not validated at all, because it’s not in the same namespace (http://my.namespace) as the schema definition. This is very dangerous, as we might easily get mislead by thinking that it validates because no errors are thrown. So how do we solve it?

We could ask the sender to provide the correct namespace in the XML file – this would be the best solution because then it would just work – if you try to validate the following XML:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8" ?>
<customer xmlns="http://my.namespace">
  <firstname>Homer</firstname>
  <lastname></lastname>
  <age>invalid</age>
</customer>

…then the validation error is thrown, because the namespaces now match:

Unfortunately, it is not always possible to change the XML file, so how can we bypass this namespace conflict? If appears that if we would change the namespace in the loaded XML document to the one we are using in our schema, the conflict is resolved. A first attempt may be:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Load the xml document
XDocument source = XDocument.Load(@"instance.xml");
// Change namespace to reflect schema namespace
source.Root.SetAttributeValue("xmlns", "http://my.namespace");
// Load the schema
XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.Add(null, XmlReader.Create(@"customer.xsd"));
// Validate
try { source.Validate(xmlSchemaSet, ValidationCallback, true); }
catch (Exception ex) { Console.WriteLine(ex.Message); } 

If we run this, the validation error is still not thrown, so setting the namespace attribute is not enough. The reason is that once the XDocument is loaded, every element in the tree gets prefixed with the namespace name. So we need to change them all, and so I wrote the following method that does this:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void Main(string[] args)
{
  // Load the xml document
  XDocument source = XDocument.Load(@"instance.xml");
  // Change namespace to reflect schema namespace
  source = SetNamespace(source,"http://my.namespace");
  // Load the schema
  XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
  xmlSchemaSet.Add(null, XmlReader.Create(@"customer.xsd"));
  // Validate
  try { source.Validate(xmlSchemaSet, ValidationCallback, true); }
  catch (Exception ex) { Console.WriteLine(ex.Message); }
}
public static XDocument SetNamespace(XDocument source, XNamespace xNamespace)
{
  foreach (XElement xElement in source.Descendants())
  {
    // First make sure that the xmlns-attribute is changed
    xElement.SetAttributeValue("xmlns", xNamespace.NamespaceName);
    // Then also prefix the name of the element with the namespace
    xElement.Name = xNamespace + xElement.Name.LocalName;
  }
  return source;
}
static void ValidationCallback(object sender, 
    System.Xml.Schema.ValidationEventArgs e)
{
  Console.WriteLine(string.Format("[{0}] {1}", e.Severity, e.Message));
} 

The SetNameSpace method will set the corrrect namespace for each element in the XDocument. And if we run it now, the validation error is thrown again because the namespace in the XDocument has been modified and matches the schema namespace.

代码语言:javascript
代码运行次数:0
运行
复制

Related

Parsing large XML filesIn "C#"

Strategy patternIn "C#"

A reference architecture (part 7)In "Architecture"

3 thoughts on “Modifying namespace in XML document programmatically”

  1. Janez says: November 18, 2010 at 4:30 pm Thanks, a working solution to a problem that took the better part of my day. :-) Reply
  2. Jim says: July 3, 2013 at 4:58 pm This solution was very hard to fine…thanks so much for posting it. Reply
  3. Mike says: June 19, 2015 at 3:51 pm This was very helpful and got me past some serious frustration! I was changing a child element tree to match a parent namespace, but I did not want to have the extra size of including the SetAttributeValue on all elements. My change was a change from one default namespace to another existing and prefixed one. This did the trick for me. Below are some minor adjustments that might be useful to others in some cases. public static XDocument SetNamespace(XDocument source, XNamespace original, XNamespace target) { //First change the element name (and namespace) foreach (XElement xElement in source.Descendants().Where(x => x.Name.Namespace == original)) xElement.Name = target + xElement.Name.LocalName; //Second, remove the default namespace attribute. foreach (XElement xElement in source.Descendants().Where(x => x.Attributes().Where(y => y.Name == “xmlns”).Count() > 0)) xElement.Attribute(“xmlns”).Remove(); return source; } Reply

Leave a Reply

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-08-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C#判断字符串是否是有效的XML格式数据
在软件开发过程中,经常需要处理XML格式的数据。XML(eXtensible Markup Language)是一种标记语言,用于存储和传输数据。它被广泛应用于配置文件、数据交换和Web服务中。因此,验证一个字符串是否是有效的XML格式数据是一个常见的需求。本文将详细介绍如何在C#中判断一个字符串是否是有效的XML格式数据,并提供一些实用的示例。
Michel_Rolle
2024/10/11
2.7K0
Linq to xml 操作带命名空间的xml
 昨天需要操作用代码操作csproj文件,实现不同vs版本的切换。 在用XElement读取了csproj文件以后怎么也获取不到想要的对象。 反反复复试验了好多次都不得要领:先看下csproj文件的内
hbbliyong
2018/03/06
1.4K0
Linq to xml 操作带命名空间的xml
C#操作XML方法集合
先来了解下操作XML所涉及到的几个类及之间的关系 如果大家发现少写了一些常用的方法,麻烦在评论中指出,我一定会补上的!谢谢大家
全栈程序员站长
2022/09/07
2.6K0
C#操作XML方法集合
Linq to XML 读取XML 备忘笔记
本文转载:http://www.cnblogs.com/infozero/archive/2010/07/13/1776383.html
跟着阿笨一起玩NET
2018/09/18
7890
Linq to XML 读取XML 备忘笔记
win10 uwp 读写XML xml 语法XmlDocumentLinq 读写 XMLWPF 读XMLWPF 读写 xaml
UWP 对 读写 XML做了一些修改,但和之前 WPF 的方法没有大的区别。 我们先来说下什么是 XML , XML 其实是 树结构,可以表达复杂的结构,所以在定制要求高的、或其他方面如json 做不到的结构,那么一般就使用XML,如果XML的数据结构都做不到,那么基本上也难找到其他的结构。 XML 的优点是读写很简单,也支持定制。缺点是复杂,当然这也是他的优点。在网络传输数据,如果使用XML,相对的传输大小会比 Json 多两倍。所以是不是要用到这么高级的结构,还是看需要。 wr 很喜欢用 XML,可以看到我们的项目,*.csproj 和页面 xaml 都是XML,当然Html也是,Xml 其实还可以用作本地数据库,所以 XML 还是很重要。 本文就提供简单的方法来读写 XML 。提供方法有两个,放在前面的方法是比较垃圾的方法,放在后面的才是我希望大家使用的。 如果遇到了 C# 或 UWP 读取 xml 返回的 Node 是空,那么请检查命名空间,关于命名空间内容,请继续看博客。
林德熙
2018/09/18
1.9K0
win10 uwp 读写XML
            xml 语法XmlDocumentLinq 读写 XMLWPF 读XMLWPF 读写 xaml
XML Schema <第三篇>
  验证XML文档是否符合议定的XML结构有两种方法,分别是DTD模式与XML Schema。本文主要介绍XML Schema。
全栈程序员站长
2021/12/23
1.5K0
XML Schema <第三篇>
C# WinForm实现自动更新程序的案例分享
string runPath = Process.GetCurrentProcess().MainModule.FileName;
用户7718188
2022/11/06
8760
WCF技术剖析之十六:数据契约的等效性和版本控制
数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据。在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交换。随着时间的推移,不可避免地,我们会面临着数据契约版本的变化,比如数据成员的添加和删除、成员名称或者命名空间的修正等,如何避免数据契约这种版本的变化对客户端现有程序造成影响,就是本节着重要讨论的问题。 一、数据契约的等效性 数据契约就是采用一种厂商中立、平台无关的形式(XSD)定义了数据的结构,而WCF通过DataContractAttribute和DataMe
蒋金楠
2018/01/16
9220
WCF技术剖析之十六:数据契约的等效性和版本控制
WinForm中使用XML文件存储用户配置及操作本地Config配置文件
大家都开发winform程序时候会大量用到配置App.config作为保持用户设置的基本信息,比如记住用户名,这样的弊端就是每个人一些个性化的设置每次更新程序的时候会被覆盖。
跟着阿笨一起玩NET
2018/09/19
3.2K0
XML Schema 复杂元素类型详解:定义及示例解析
您还可以基于现有的复杂类型创建新的复杂类型,并在其中添加额外的元素,如上面的第二个示例所示。
小万哥
2024/05/18
1480
XML Schema 复杂元素类型详解:定义及示例解析
C#操作XML文件
明志德道
2023/10/21
2390
C#操作XML文件
LINQ 从 CSV 文件生成 XML
本文参考:http://msdn.microsoft.com/zh-cn/library/bb387090.aspx
跟着阿笨一起玩NET
2018/09/19
1.3K0
LINQ to XML LINQ学习第一篇
1、LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: public static void CreateDocument() { string p
hbbliyong
2018/03/05
1.6K0
LINQ to XML  LINQ学习第一篇
XML 和 JSON
不久前看到一个讨论帖,说的是 XML 和 JSON 的比较,说着说着后来就变成了 JSON 到底比 XML 牛逼在哪里。不吹不黑,客观地来比较一下二者的异同。
四火
2022/07/19
7490
XML 和 JSON
Using XPaths in Message Assignment[转]
Microsoft BizTalk Server 2004 Using XPaths in Message Assignment You can use the xpath function to assign an XPath value to a message part, or to assign a value to an XPath that refers to a message part. For more information on assigning to messages and me
阿新
2018/04/12
7360
C# - DynamicObject with Dynamic
本文转载:http://joe-bq-wang.iteye.com/blog/1872756
跟着阿笨一起玩NET
2018/09/19
8090
【深入浅出C#】章节 9: C#高级主题:LINQ查询和表达式
C#高级主题涉及到更复杂、更灵活的编程概念和技术,能够让开发者更好地应对现代软件开发中的挑战。其中,LINQ查询和表达式是C#高级主题中的一项关键内容,具有以下重要性和优势:
喵叔
2023/08/21
2.6K0
Unimelb COMP20008 Note 2019 SM1 - Data formats
-Appreciate the role that relational databases play in data wrangling.
403 Forbidden
2021/05/17
5330
我的WCF之旅(10):如何在WCF进行Exception Handling
在任何Application的开发中,对不可预知的异常进行troubleshooting时,异常处理显得尤为重要。对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地实现这一功能。但是对于 一个分布式的环境来说,异常处理就没有那么简单了。按照面向服务的原则,我们把一些可复用的业务逻辑以Service的形式实现,各个Service处于一个自治的环境中,一个Service需要和另一个Service进行交互,只需要获得该Service的描述(Description)就可以了(比如WSDL,Sc
蒋金楠
2018/02/07
5620
我的WCF之旅(10):如何在WCF进行Exception Handling
微信快速开发框架(二) -- 快速开发微信公众平台框架---简介
年底了,比较忙,大家都在展望未来,对于30+的我来说,发展和稳定是个难以取舍的问题。最近发了些求职信,鸟无音讯,没事做,做点帮助大家的东西吧。 之前做了个微信公众平台的查询系统,在开发中,发觉了一些微信公众平台的接口问题《对微信公众平台开发的消息处理》,开发起来比较痛苦,对于微信过来的消息,需要解析后一个一个来返回,编写之痛苦,相信有人明白。在开发中,一直考虑着如何来简化开发,暂时想不到好的模式来开发,就自己胡乱写了一个,希望对大家有帮助。 代码已发布到github:https://github.com/
脑洞的蜂蜜
2018/02/01
2K0
微信快速开发框架(二) -- 快速开发微信公众平台框架---简介
相关推荐
C#判断字符串是否是有效的XML格式数据
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验