I'm ashamed to even post this, as Dare and Oleg will likely balk at the audacity and pure poo of the solution.

我什至不敢发布此消息,因为Dare和Oleg可能会对解决方案的胆大妄为和纯洁无情。

That said, sometimes you have to support a legacy evil, er, solution and one's (mine) overdeveloped sense of code smell must be supressed.

就是说,有时候您必须支持一种传统的邪恶,错误,解决方案,并且必须抑制一个人(我的)过度开发的代码气味。

So, there's some XML, it's as a schema and it's cool and strongly typed. It might look something like:

因此,有一些XML,它是一种架构,非常酷且类型强。 它可能看起来像:

<?xml version="1.0" encoding="utf-16"?><ns0:SignOnResponse xmlns:ns0="http://www.corillian.com/Voyager/Authentication/Messages/2004/05"><ns1:Header xmlns:ns1=http://www.corillian.com/operations/2004/11">
<ns1:Something>somethingCoolio</ns1:Something>
...blah blah blah...
</ns0:SignOnResponse>

<?xml版本=“ 1.0”编码=“ utf-16”?> <ns0:SignOnResponse xmlns:ns0 =“ http://www.corillian.com/Voyager/Authentication/Messages/2004/05”> <ns1:标题xmlns:ns1 = http://www.corillian.com/operations/2004/11“> <ns1:Something>某事很酷</ ns1:Something> ...等等等等等等... </ ns0:SignOnResponse>

You get the idea...it's generated, but it's legit. Here's the weird part...for a legacy app, another XML Document (arguably a Fragment) is "tunnelled" within one of the the larger document's elements:

您明白了...产生了主意,但这是合法的。 这是一个奇怪的部分...对于旧版应用程序,另一个XML文档(可以说是Fragment)被“隧道化”在较大文档的元素之一中:

<ns1:Something><![CDATA[<holycrap><sweetlord>it's another xml document! hiding inside! Wow, it has no namespace? Oy.</sweetlord></holycrap>]]</ns1:Something>

<ns1:Something> <![CDATA [<holycrap> <sweetlord>这是另一个xml文档! 躲在里面! 哇,它没有名称空间吗? Oy。</ sweetlord> </ holycrap>]] </ ns1:Something>

Notice above that there's another entirely different document inside the larger one.  Additionally the fragment has a root node of "sweetlord" perhaps I want it to be deserialized into a "SomethingType." Since "SomethingType" was defined in XSD and generated earlier, I can't change it's [XmlRoot] without editing the generated code.

请注意,在上面的文档中,还有一个完全不同的文档。 另外,该片段的根节点为“ sweetlord”,也许我希望将其反序列化为“ SomethingType”。 由于“ SomethingType”是在XSD中定义的,并且是较早生成的,因此,如果不编辑生成的代码,便无法更改其[XmlRoot]。

But, I can override it. So, this technique below shows two things.

但是,我可以覆盖它。 因此,下面的这项技术展示了两件事。

  • Taking an Xml fragment that has no namespace and fooling the XmlSerializer (or any XmlTextReader consumer) into thinking it does using Clemen's/Chris's (dasBlog's/BlogX's) XmlNamespaceUpgrading Reader.拿一个没有名称空间的Xml片段,并欺骗XmlSerializer(或任何XmlTextReader使用者),使其认为使用Clemen / Chris(dasBlog / BlogX)的XmlNamespaceUpgrading Reader确实起作用。
  • Using XmlAttributeOverrides to force the XmlSerializer to "no no, use THIS XmlRootAttribute!"使用XmlAttributeOverrides强制XmlSerializer设置为“否,请使用XmlRootAttribute!”

// The Something property is a string containing an Xml Fragment

// Something属性是一个包含Xml片段的字符串

// as shown above. That fragment has no namespace, but there is a

//如上所示。 该片段没有名称空间,但是有一个

// generated object WITH a namespace that it could deserialize into

//生成的对象带有可以反序列化为的名称空间

// (it matches the "data contract.")

//(与“数据协定”匹配。)

string tunnelledString = myLargerResponse.Something;

字符串tunnelledString = myLargerResponse.Something;

if(savedSerializer == null)

如果(savedSerializer == null )

{

{

XmlRootAttribute xra = new XmlRootAttribute("holycrap");

XmlRootAttribute xra =新的XmlRootAttribute(“ holycrap”);

xra.Namespace = "http://www.corillian.com/something/messages/2004/05";

xra.Namespace =“ http://www.corillian.com/something/messages/2004/05”;

XmlAttributes attrs = new XmlAttributes();

XmlAttributes attrs =新的XmlAttributes();

attrs.XmlRoot = xra;

attrs.XmlRoot = xra;

XmlAttributeOverrides over = new XmlAttributeOverrides();

XmlAttributeOverrides over =新的XmlAttributeOverrides();

over.Add(typeof(SomethingType),attrs);

over.Add( typeof (SomethingType),attrs);

savedSerializer = new XmlSerializer(

savedSerializer =新的XmlSerializer(

typeof(SomethingType),

typeof (SomethingType),

over);

过度);

}

}

SomethingType info = savedSerializer.Deserialize(

SomethingType info = savedSerializer.Deserialize(

new XmlNamespaceUpgradeReader(

新的XmlNamespaceUpgradeReader(

new StringReader(tunnelledString),

新的StringReader(tunnelledString),

String.Empty,

String.Empty,

"http://www.corillian.com/something/messages/2004/05"))

“ http://www.corillian.com/something/messages/2004/05”))

as SomethingType;

作为SomethingType;

Here's the XmlNamespaceUpgradeReader. Notice that it's used above passing in String.Empty as the oldNamespaceUri, and the namespace we WISH it had as the newNamespaceUri. That's the namespace we told the XmlSerializer in the AttributeOverrides.

这是XmlNamespaceUpgradeReader。 请注意,上面使用它时将String.Empty传递为oldNamespaceUri,而我们希望它具有的命名空间为newNamespaceUri。 那就是我们在AttributeOverrides中告诉XmlSerializer的名称空间。

Note also that we save away the XmlSerializer because of the XmlSerializer leak for its complex constructor overrides. As an alternative to saving it off, we could use the very cool Mvp.Xml.XmlSerializerCache.

还要注意,由于XmlSerializer泄漏了它的复杂构造函数,所以我们省去了XmlSerializer。 作为保存它的替代方法,我们可以使用非常酷的Mvp.Xml.XmlSerializerCache 。

public class XmlNamespaceUpgradeReader : XmlTextReader

公共类XmlNamespaceUpgradeReader:XmlTextReader

{

{

string oldNamespaceUri;

字符串oldNamespaceUri;

string newNamespaceUri;

字符串newNamespaceUri;

public XmlNamespaceUpgradeReader( TextReader reader, string oldNamespaceUri, string newNamespaceURI ):base( reader )

公共XmlNamespaceUpgradeReader(TextReader reader,字符串oldNamespaceUri,字符串newNamespaceURI):基本(reader)

{

{

this.oldNamespaceUri = oldNamespaceUri;

这个.oldNamespaceUri = oldNamespaceUri;

this.newNamespaceUri = newNamespaceURI;

这个.newNamespaceUri = newNamespaceURI;

}

}

public override string NamespaceURI

公共重写字符串NamespaceURI

{

{

get

得到

{

{

// we are assuming XmlSchemaForm.Unqualified, therefore

//我们假设XmlSchemaForm.Unqualified,因此

// we can't switch the NS here

//我们无法在此处切换NS

if ( this.NodeType != XmlNodeType.Attribute &&

如果(此.NodeType!= XmlNodeType.Attribute &&

base.NamespaceURI == oldNamespaceUri )

base .NamespaceURI == oldNamespaceUri)

{

{

return newNamespaceUri;

返回newNamespaceUri;

}

}

else

其他

{

{

return base.NamespaceURI;

返回基础.NamespaceURI;

}

}

}

}

}

}

}

}

翻译自: https://www.hanselman.com/blog/enabling-evil-tunnelling-xml-within-xml-using-the-xmlserializer-and-some-magic

启用邪恶-使用XmlSerializer和一些魔术在Xml中隧道化Xml相关推荐

  1. 解决WSL2报错(请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化[已退出进程,代码为 4294967295])

    在启动WSL时出现报错 请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化.有关信息,请访问 https://aka.ms/wsl2-install [已退出进程,代码为 4294 ...

  2. 请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化。模块“vpmc”启动失败。未能启动虚拟机。

    请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化. wsl kali或者Ubuntu启动告警显示:请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化.能百度到 ...

  3. wsl set default version: 请启用虚拟机平台 windows 功能并确保在 bios 中启用虚拟化

    ​ 前段时间电脑偶然间恢复了出厂设置,之前安装的docker之类的东西都得重来了. 既然要安装docker,肯定得用到WSL,于是就想要先把WSL的版本切换到2. 在运行了如下命令后出现了这么个问题 ...

  4. python魔术方法print_Python中的魔术方法入门

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",中文称『魔术方法』,例如类的初始化方法 __init__ ,P ...

  5. php5的魔术方法,php5中魔术方法学习笔记

    1.__construct() 当实例化一个对象的时候,这个对象的这个方法首先被调用. PHP实例代码如下: classTest {function__construct() {echo"b ...

  6. 列举php中常见的魔术方法,PHP 中常用的 9 个魔术方法

    这个标题有点牵强因为php有不只9种魔术方法, 但是这些将会引导你使用php魔术方法一个好的开始.它可能魔幻,但是并不需要魔杖. 这些'魔术'方法拥有者特殊的名字,以两个下划线开始,表示这些方法在ph ...

  7. 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法

    ↑ 点击蓝字 关注极市平台作者丨SFXiang来源丨AI算法修炼营编辑丨极市平台 极市导读 本文从降低下采样率与空洞卷积.多尺度训练.优化Anchor尺寸设计.深层和浅层特征融合等多个方面入手,对目标 ...

  8. wps启用编辑按钮在哪里_在wps工具栏中添加按钮的方法介绍

    在工具栏上点右键->自定义,会打开一个 "自定义" 对话框.这个对话框的第二个选项卡 "命令(&C)" 中可以对菜单栏和各个工具栏的命令和按钮进行 ...

  9. ssh(Struts+spring+Hibernate)三大框架整合-简述

    ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...

  10. android interview 1

    1.    请描述下Activity的生命周期.       必调用的三个方法:onCreate() --> onStart() --> onResume(),用AAA表示 (1)父Act ...

最新文章

  1. socket编程:I/O模型
  2. 关于计算机图形标准化的论述 哪个是正确的,地大《计算机图形学(新)》在线作业 参考资料...
  3. 傲游浏览器怎么更换皮肤 浏览器皮肤更换方法简述
  4. linux popen管道,linux进程通信之标准流管道popen
  5. SQL SERVER 2000数据库,转换为ACCESS数据库(已解决ACCESS自动编号问题)
  6. 国产CAD_手机也能看CAD图纸了?国产软件助力CAD告别电脑时代!
  7. 双足机器人重心在头部_双足行走机器人及其重心调节装置制造方法及图纸
  8. 受保护的Word文档如何编辑?
  9. 电脑热点突然不能用了,想想你是否新装了VMware等软件
  10. 2021年茶艺师(初级)考试题库及茶艺师(初级)作业考试题库
  11. 期货反向跟单--有趣儿的差异化
  12. 达人评测 小米笔记本pro14和联想yoga14s 选哪个好
  13. 配置windows 静态IP地址
  14. 树上分治算法 + 路径剖分
  15. java:对字母进行大写(小写)的转化
  16. 实现宏offsetof()
  17. 鹿鼎记 / Royal Tramp (1992)
  18. 2020-3-17课堂笔记
  19. Chrome的控制台(Console)的用法(超详细,还未细看)
  20. java8通过 poi+text 将word转为pdf

热门文章

  1. 数据结构课程设计——电话号码查询系统(C语言)
  2. android webview 电脑网页适应手机屏幕
  3. 凉宫春日的忧郁[数学题]
  4. 世界记忆大师张杰和王茂华培训总结
  5. Netstat -tln 命令是Linux查看端口使用情况
  6. mysql-mmm架构深度详解
  7. 华罗庚 计算机,华罗庚有关计算机的故事
  8. 利用计算机进行有理数的运算教学反思,有理数乘法分配律教学反思
  9. 数据结构与算法-链表实现
  10. 微信开发工具如何修改模拟页面路径