我正在攻击第三方xml api。他们定义了一个类似于以下内容的必需xml结构。
<ns1:E xmlns:ns1="schema">
<ns1:B>
<ns2:S>
<ns2:V>
<ns2:Bl />
</ns2:V>
</ns2:S>
</ns1:B>
</ns1:E>
有一个SQL表,其中包含我需要放入此xml格式的信息。我有一个LINQ to SQL适配器来获取数据,我使用System.Xml
来创建XML文档。
XmlDocument.CreateElement("ns1:E"); etc
只要从元素名称中删除冒号,这就可以正常工作。使用冒号,只有冒号的右侧是元素名称。我知道冒号是禁止的,但我无法控制第三方api的命令。
有什么方法可以解决这个问题?是否有任何有用的方法可以强制冒号进入元素名称?我不必使用XMLDocument
但不确定其他方法会让我在那里。
更新:我意识到<ns1:
指的是命名空间。是的,有2.当写出XML时,如果我说 -
XmlDocument.CreateElement(ns1:E", "http://schema);
但是,这个的XML输出是
<ns1:E xmlns:ns1="http://schema">
如果我只说XmlDocument.CreateElement("ns1:E");
没有uri,那么输出只是<E>
。我不希望输出具有架构引用,但我需要有前缀。我想要实现的结果只是<ns1:E>
。两个namspace都在顶部声明,我认为这意味着我必须在每个节点声明它们。
答案 0 :(得分:12)
好的,就是这样。
XmlDocument.CreateElement("prefix", "name", "uri");
如果它可以帮助其他人,请参考此处:http://msdn.microsoft.com/en-us/library/c22k3d47.aspx 1
答案 1 :(得分:5)
冒号表示这些元素位于ns1 namespace中。使用多个模式时需要这样做。假设文档仅使用ns1,它基本上等同于那些标签中没有任何“ns1:”。有关详细信息,请参阅this guide。
答案 2 :(得分:5)
您发布的XML文档实际上并不是格式正确,因为分配给许多元素的ns2
缩写与命名空间无关。固定,它可能看起来像这样:
<ns1:E xmlns:ns1="schema" xmlns:ns2="my-namespace">
<ns1:B>
<ns2:S>
<ns2:V>
<ns2:Bl />
</ns2:V>
</ns2:S>
</ns1:B>
</ns1:E>
上述XML文档在语义上等同于此文档:
<s:E xmlns:s="schema">
<s:B>
<S xmlns="my-namespace">
<m:V xmlns:m="my-namespace">
<s:Bl xmlns:s="my-namespace"/>
</m:V>
</S>
</s:B>
</s:E>
对于这个:
<E xmlns="schema">
<B xmlns="schema">
<S xmlns="my-namespace">
<V>
<Bl/>
</V>
</S>
</B>
</E>
在所有三种情况下,E
和B
元素都在schema
命名空间中,而S
,V
和{{1} }元素位于Bl
命名空间中。
命名空间前缀很有用,但严格来说,它们是不必要的。您可以像上一个示例一样创建不使用前缀的XML文档,并为每个元素显式声明名称空间。
如果在处理XML时,您认为您关心给定元素使用的前缀,那么您几乎肯定是错的。你唯一关心的是它所属的命名空间。例如,如果我将这三个文档中的任何加载到my-namespace
中,则以下代码将写出'Bl'元素:
XmlDocument
当你说:
我不希望输出具有架构引用,但我需要有前缀。我想要实现的结果只是
XmlNamespaceManager ns = new XmlNamespaceManager(d.NameTable); ns.AddNamespace("a", "schema"); ns.AddNamespace("b", "my-namespace"); Console.Write(d.SelectSingleNode("/a:E/a:B/b:S/b:V/b:Bl", ns).OuterXml);
。
你几乎肯定是错误的。标记为<ns1:E>
的元素没有意义,除非ns1:E
前缀映射到该元素或其祖先之一的命名空间。 (另外,命名空间不是架构引用。)如果使用
ns1
创建元素,然后将它附加到已经声明CreateElement("ns1", "E", "schema");
作为ns1
命名空间的前缀的元素,然后DOM将附加没有命名空间声明的元素,因为在这种情况下,它是不需要的。如果未声明schema
(或声明为缩写ns1
以外的某些命名空间),则DOM将在元素和前缀上添加名称空间声明。
tl; dr:你关心命名空间,而不关心名称空间前缀。
答案 3 :(得分:3)
(我知道这是一个老问题,但是我正在做一些相同的事情并想出如何挥动死鸡以使其发挥作用。我正在记录它以便我以后可以找到它。)
string myName = "foo"; string ns_local = root.GetNamespaceOfPrefix("local"); string ns_x = root.GetNamespaceOfPrefix("x"); System.Xml.XmlNode newNode = doc.CreateNode(System.Xml.XmlNodeType.Element, "local", "MyTag", ns_local); System.Xml.XmlNode attr = doc.CreateNode(System.Xml.XmlNodeType.Attribute, "Key", ns_x); attr.Value = myName; newNode.Attributes.SetNamedItem(attr); attr = doc.CreateNode(System.Xml.XmlNodeType.Attribute, "MyAttr", ""); attr.Value = myName; newNode.Attributes.SetNamedItem(attr); nodeToAppendTo.AppendChild(newNode);
这给了我一个看起来像
的标签<local:MyTag x:Key="foo" MyAttr="foo" />
答案 4 :(得分:2)
<ns1:E xmlns:ns1="schema">
<ns1:B>
<ns2:S>
<ns2:V>
<ns2:Bl />
</ns2:V>
</ns2:S>
</ns1:B>
</ns1:E>
因此,要使用Create XmlElement获取上述输出,可以按如下方式实现:
CreateElement("ns1","E", "schema");
CreateElement("ns1","B", "schema");
CreateElement("ns2","S", "schema");
CreateElement("ns2","V", "schema");
CreateElement("ns2","B1", "schema");
这里元素&#34; E&#34;是根元素,所以它前缀为&#34; ns1&#34;以及架构。
由于所有其他提及的元素如&#34; B&#34;,&#34; S&#34;,&#34; V&#34;,&#34; B1&#34;是孩子的元素&#34; E&#34;它带有前面提到的前缀,但不再次显示子元素的架构。
因此,您可以使用根元素中的模式获得上述所需的输出,并且只获得子元素的前缀。
答案 5 :(得分:0)
冒号前面的单词是命名空间。如果你想要一个元素“ns1:E”,你需要创建一个名为“E”的元素并将其命名空间设置为“ns1”。