我正在攻击第三方xml api.他们定义了一个类似于以下所需的xml结构.
<ns1:E xmlns:ns1="schema">
<ns1:B>
<ns2:S>
<ns2:V>
<ns2:Bl />
</ns2:V>
</ns2:S>
</ns1:B>
</ns1:E>
Run Code Online (Sandbox Code Playgroud)
有一个SQL表,其中包含我需要放入此xml格式的信息.我有一个LINQ to SQL适配器来获取数据,我正在使用a System.Xml来创建XML文档.
XmlDocument.CreateElement("ns1:E"); etc
Run Code Online (Sandbox Code Playgroud)
只要我从元素名称中删除冒号,这样就可以正常工作.使用冒号,只有冒号的右侧是元素名称.我知道冒号是禁止的,但我对第三方api所指控的内容没有任何控制权.
有什么方法可以解决这个问题?是否有任何有用的方法可以强制冒号进入元素名称?我不必使用XMLDocument但不确定其他方法会让我在那里.
更新:我意识到指的<ns1:是命名空间.是的,有2.当写出XML时,如果我说 - 我可以让它工作 -
XmlDocument.CreateElement(ns1:E", "http://schema);
Run Code Online (Sandbox Code Playgroud)
但是,这是XML输出
<ns1:E xmlns:ns1="http://schema">
Run Code Online (Sandbox Code Playgroud)
如果我只是说XmlDocument.CreateElement("ns1:E");没有uri,那么输出就是<E>.我不希望输出具有架构引用,但我需要有前缀.我想要实现的结果很简单<ns1:E>.两个namspace都在顶部声明,我认为这意味着我必须在每个节点声明它们.
在我看来web method,我得到了一些第三方C#实体类的对象.实体类只不过是DataContract.这个实体类非常复杂,具有各种类型的属性,一些属性也是集合.当然,这些链接类型也是DataContracts.
我想将该DataContract实体序列化为XML,作为我的Web服务的业务逻辑的一部分.我不能DataContractSerializer直接使用(在我在web方法中收到的对象),因为XML模式完全不同. 因此,DataContractSerializer生成的XML不会针对模式进行验证.
我无法总结出我应该遵循的方法来实施.我可以想到以下实施方法:
LINQ to XML - 这看起来不错,但我需要为每种类型的对象手动创建XML树(即类实例的元素或XML表示).由于有许多实体类并且它们彼此链接,我认为手动编写XML元素太多了.此外,当实体类引入一些新属性时,我将不得不继续修改XML树.不仅如此,我生成XML树的代码看起来有点笨拙(至少在外观上)并且将来很难被其他开发人员维护/更改; 他/她将不得不仔细研究它以了解如何生成XML.
XmlSerializer - 我可以编写自己的实体类来表示我想要的XML结构.现在,我需要将传入对象的详细信息复制到我自己的类的对象中.所以这是额外的工作(对于.NET,当代码执行时也是如此!).然后我可以XmlSerializer在我的对象上使用生成XML.在这种情况下,我将不得不创建实体类,每当第三方实体被修改时,我只需要在我的类中添加新属性.(使用XmlElement或XmlAttibute属性).但人们推荐DataContractSerializer这个,所以我不想最终确定这个,除非我清楚所有方面.
DataContractSerializer - 再次在这里,我将不得不编写自己的实体类,因为我无法控制第三方DataContracts.我需要将传入对象的细节复制到我自己的类的对象中.所以这是额外的工作.但是,由于DataContractSerializer不支持Xml属性,因此我必须IXmlSerializable在WriteXml方法中实现并生成所需的Xml .DataContractSerializer比XmlSerializer更快,但如果第三方实体发生变化,我将不得不处理更改(在WriteXml中).
问题:
DataContractSerializer值得考虑(因为它具有更好的性能XmlSerilaizer)?serialization xml-serialization .net-4.0 linq-to-xml datacontractserializer
我是新手,XML并尝试了以下但我得到了一个例外.有人能帮我吗?
例外是 This operation would create an incorrectly structured document
我的代码:
string strPath = Server.MapPath("sample.xml");
XDocument doc;
if (!System.IO.File.Exists(strPath))
{
doc = new XDocument(
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ"))),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS"))));
doc.Save(strPath);
}
Run Code Online (Sandbox Code Playgroud) 我有一个没有root的XML文件.我无法改变这一点.我试图解析它,但XDocument.Load不会这样做.我试图设置ConformanceLevel.Fragment,但我仍然抛出异常.有人有解决方案吗?
我尝试过XmlReader,但事情搞砸了,无法正常工作.XDocument.Load效果很好,但是如果我有一个有多个根的文件,它就没有.
我有一个项目,我正在采取一些特别丑陋的"实时"HTML,并使用HTML Agility Pack将其强制转换为正式的XML DOM.我希望能够做的是用Linq对XML进行查询,以便我可以清除我需要的位.我正在使用此处描述的方法将HtmlDocument解析为XDocument,但在尝试查询时我不知道如何处理命名空间.在一个特定的文档中,原始HTML实际上是格式不正确的XHTML,带有以下标记:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
Run Code Online (Sandbox Code Playgroud)
当试图从这个文档中查询时,似乎命名空间属性阻止我做类似的事情:
var x = xDoc.Descendants("div");
// returns null
Run Code Online (Sandbox Code Playgroud)
显然,对于那些"div"标签,只有LocalName是"div",但正确的标签名称是名称空间加上"div".我试图对XML命名空间的问题进行一些研究,似乎我可以通过这种方式来绕过命名空间:
var x =
(from x in xDoc.Descendants()
where x.Name.LocalName == "div"
select x);
// works
Run Code Online (Sandbox Code Playgroud)
但是,这似乎是一个相当hacky的解决方案,并没有正确解决名称空间问题.据我所知,一个正确的XML文档可以包含多个名称空间,因此处理它的正确方法应该是解析我正在查询的名称空间.还有其他人不得不这样做吗?我只是想让它变得复杂吗?我知道我可以通过坚持使用HtmlDocument并使用XPath查询来避免所有这些,但如果可能的话,我宁愿坚持我所知道的(Linq),我也更愿意知道我没有为更进一步的命名空间做好准备 - 相关问题在路上.
在这种情况下处理命名空间的正确方法是什么?
单元测试我的序列化代码我发现一个失败,因为我有一个不同的顺序列出的属性(我只是比较XDocument.ToString()值),虽然我可以修复它,它对我来说无关紧要的顺序只要元素或属性在正确的层次结构中具有正确的名称,它们就会出现.我可能会写一个方法来做这个,但我想知道是否有一个我不知道的简单内置方式.
我试图打开这样的xmldocument:
var doc = new XDocument("c:\\temp\\contacts.xml");
var reader = doc.CreateReader();
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
namespaceManager.AddNamespace("g", g.NamespaceName);
var node = doc.XPathSelectElement("/Contacts/Contact/g:Name[text()='Patrick Hines']", namespaceManager);
node.Value = "new name Richard";
doc.Save("c:\\temp\\newcontacts.xml");
Run Code Online (Sandbox Code Playgroud)
我在第一行返回错误:
Non whitespace characters cannot be added to content.
Run Code Online (Sandbox Code Playgroud)
xmlfile看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<Contacts xmlns:g="http://something.com">
<Contact>
<g:Name>Patrick Hines</g:Name>
<Phone>206-555-0144</Phone>
<Address>
<street>this street</street>
</Address>
</Contact>
</Contacts>
Run Code Online (Sandbox Code Playgroud) 现在,我意识到此前提出过这类问题(特别是这个 - 我认为这是对两个对象的非常好的描述).我的问题更多是围绕表现.我有几个XML文档,大小超过100 - 300 K. 我注意到将这些信息加载到一个XDocument而不是一个XmlDocument对象时会有一些延迟.这两个对象之间是否存在严重的性能差异?他们是否以不同方式访问XML的内容?使用XML字符串时,这是首选的,或者是有区别的.这些对象的最终用途是XPath在有问题的对象上运行查询(或LINQ,取决于).
同样,这主要是性能问题,涉及内存和速度.
我需要创建以下XML,我正在尝试使用XDocument.但是,我在指定名称空间时遇到了麻烦.
<AssessmentOrderRequest
xsi:schemaLocation="http://ns.hr-xml.org/2007-04-15 http://ns.hr-xml.org/2_5/HR-XML-2_5/StandAlone/AssessmentOrderRequest.xsd"
xmlns="http://ns.hr-xml.org/2007-04-15"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</AssessmentOrderRequest>
Run Code Online (Sandbox Code Playgroud)
这是我正在寻找的那种代码,但是,我无法在名称中创建带冒号的属性xsi:schemaLocation.
return new XDocument(
new XElement("AssessmentOrderRequest",
new XAttribute("xsi:schemaLocation", XNamespace.Get("http://ns.hr-xml.org/2007-04-15 http://ns.hr-xml.org/2_5/HR-XML-2_5/StandAlone/AssessmentOrderRequest.xsd")),
new XAttribute("xmlns", XNamespace.Get("http://ns.hr-xml.org/2007-04-15")),
new XAttribute(XNamespace.Xmlns + "xsi", XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"))
)
);
Run Code Online (Sandbox Code Playgroud) 我有这样的XML结果
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">16</int>
</lst>
<result name="response" numFound="3" start="0" maxScore="1.0">
<doc>
<str name="ContaFirstname">
firstname1
</str>
<str name="ContaId">6557</str>
<str name="ContaJobTitle">Manager</str>
<str name="ContaSurname">surname1
</str>
</doc>
<doc>
<str name="ContaFirstname">firstname2</str>
<str name="ContaId">6203</str>
<str name="ContaJobTitle">Director</str>
<str name="ContaSurname">surname2</str>
</doc>
</result>
</response>
Run Code Online (Sandbox Code Playgroud)
我想获得对象的列表,每个对象将包含的价值ContaFirstname,ContaId,ContaJobTitle和ContaSurname
我试过这样的东西,但这不对,因为我把它们都弄得一团糟
var test = from c in xml.Descendants("doc")
select new
{
firstname = c.Element("ContaFirstname"),
surnmane = c.Element("ContaSurname")
};
Run Code Online (Sandbox Code Playgroud)
那么如何通过名称访问这些元素呢?
linq-to-xml ×10
xml ×8
c# ×5
.net ×3
linq ×2
namespaces ×2
.net-4.0 ×1
asp.net ×1
c#-4.0 ×1
html ×1
performance ×1
xmldocument ×1
xnamespace ×1