带冒号的 xml 元素名称

发布于 2024-08-12 17:44:18 字数 1091 浏览 3 评论 0 原文

我正在使用第 3 方 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

只要我从元素名称中删除冒号,这就可以正常工作。对于冒号,只有冒号的右侧出现在元素名称中。我知道冒号是禁忌,但我无法控制第 3 方 api 的规定。

我有什么办法可以解决这个问题?有什么有用的方法可以强制将冒号放入元素名称中吗?我不必使用 XMLDocument 但不确定还有什么其他方法可以让我到达那里。

更新:我意识到 指的是命名空间。是的,有 2 个。当写出 XML 时,如果我说 -

 XmlDocument.CreateElement("ns1:E", "http://schema");

但是,它的 XML 输出是

<ns1:E xmlns:ns1="http://schema">

如果我只是说 XmlDocument.CreateElement("ns1:E");XmlDocument.CreateElement("ns1:E"); 没有 uri,那么输出只是 。我不希望输出具有架构引用,但我确实需要具有前缀。我想要实现的结果很简单 。两个命名空间都在顶部声明,我认为这意味着我必须在每个节点声明它们。

I'm working against a 3rd party xml api. They have defined a required xml structure similar to the following.

<ns1:E xmlns:ns1="schema">
<ns1:B>
    <ns2:S>
        <ns2:V>
            <ns2:Bl />
        </ns2:V>
    </ns2:S>
</ns1:B>
</ns1:E>

There is a SQL table with the information that I need to put into this xml format. I have a LINQ to SQL adapter to get the data and I'm using a System.Xml to create an XML document.

XmlDocument.CreateElement("ns1:E"); etc

This works fine as long as I remove the colons from the element names. With the colons, only the right hand side of the colon is in the element name. I know colons are a no-no but I don't have any control over what the 3rd party api is dictating.

What are my options for getting around this? Are there any useful ways of forcing the colons into the element names? I don't have to use XMLDocument but not sure what other method will get me there.

UPDATE: I realize that the <ns1: refers to a namespace. And yes, there are 2. When writing out the XML, I can make it work if I say -

 XmlDocument.CreateElement("ns1:E", "http://schema");

However, the XML output of this is

<ns1:E xmlns:ns1="http://schema">

If I just say XmlDocument.CreateElement("ns1:E"); with no uri, then the output is just <E>. I don't want the output to have the schema reference but I do need to have the prefix. The result I want to achieve is simply <ns1:E>. Both namspaces are declared at the top which I would think would mean I would have to declare them at every node.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

栀子花开つ 2024-08-19 17:44:18

好的,就在这里。

XmlDocument.CreateElement("prefix", "name", "uri");

如果对其他人有帮助,请参考此处: http://msdn.microsoft.com/en -us/library/c22k3d47.aspx 1

Okay, here it is.

XmlDocument.CreateElement("prefix", "name", "uri");

reference here if it helps someone else: http://msdn.microsoft.com/en-us/library/c22k3d47.aspx 1

不乱于心 2024-08-19 17:44:18

冒号表示这些元素位于 ns1 命名空间 中。当您使用多个模式时,这是需要的。假设文档仅使用 ns1,则本质上相当于这些标签中没有任何“ns1:”。有关详细信息,请参阅本指南

The colons indicate that those elements are in the ns1 namespace. This is needed when you are using multiple schemas. Assuming the document only uses ns1, it is essentially equivalent to not having any "ns1:" in those tags. See this guide for more info.

柳若烟 2024-08-19 17:44:18

您发布的 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>

在所有三种情况下, EB 元素都位于schema 命名空间,而 SVBl 元素位于 my-namespace 中 命名空间。

命名空间前缀很有用,但严格来说它们是不必要的。您可以创建 XML 文档,如上一个示例,不使用前缀,并为每个元素显式声明命名空间。

如果在处理 XML 时您认为自己关心给定元素使用的前缀,那么您几乎肯定是错的。您唯一关心的是它属于哪个名称空间。例如,如果我将这三个文档中的任何一个加载到 XmlDocument 中,以下代码将写出“Bl”元素:

    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 前缀映射到该元素或其祖先之一中的命名空间。 (此外,命名空间不是架构引用。)如果您使用

CreateElement("ns1", "E", "schema");

来创建元素,然后将其附加到已将 ns1 声明为 schema< 的前缀的元素/code> 命名空间,那么 DOM 将在没有命名空间声明的情况下附加元素,因为在该上下文中不需要它。如果 ns1 未声明(或者被声明为除 schema 之外的某个名称空间的缩写),则 DOM 会将名称空间声明粘贴到元素以及前缀上。

tl;dr:您关心名称空间,而不是名称空间前缀。

The XML document you posted is not actually well-formed, because the ns2 abbreviation assigned to many of the elements is not associated with a namespace. Fixed, it might look like this:

<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>

The above XML document is semantically equivalent to this one:

<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>

And to this one:

<E xmlns="schema">
  <B xmlns="schema">
    <S xmlns="my-namespace">
      <V>
        <Bl/>
      </V>
    </S>
  </B>
</E>

In all three cases, the E and B elements are in the schema namespace, while the S, V, and Bl elements are in the my-namespace namespace.

Namespace prefixes are helpful, but strictly speaking they're unnecessary. You can create XML documents, like the last example, that use no prefixes, and that declare the namespace explicitly for every element.

If, in processing XML, you think you care what prefix a given element is using, you're almost certainly wrong. The only thing you care about is what namespace it belongs to. For instance, if I load any of those three documents into an XmlDocument, the following code will write out the 'Bl' element:

    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);

When you say:

I don't want the output to have the schema reference but I do need to have the prefix. The result I want to achieve is simply <ns1:E>.

you are almost certainly in error. An element whose tag is ns1:E is meaningless unless the ns1 prefix is mapped to a namespace, either in that element or in one of its ancestors. (Also, a namespace is not a schema reference.) If you use

CreateElement("ns1", "E", "schema");

to create the element, and then append it to an element that has already declared ns1 as being the prefix for the schema namespace, then the DOM will append the element without the namespace declaration, because in that context it isn't needed. If ns1 isn't declared (or is declared as abbreviating some namespace other than schema), then the DOM will stick a namespace declaration onto the element as well as the prefix.

tl;dr: You care about namespaces, not namespace prefixes.

虐人心 2024-08-19 17:44:18

(我知道这是一个老问题,但我正在做一些等效的事情,并弄清楚如何挥动死鸡使其工作。我正在记录它,以便以后可以找到它。)

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" />

(I know it's an old question, but I'm doing something equivalent and figured out how to wave the dead chicken to make it work. I'm documenting it so I can find it later.)

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);

This gives me a tag that looks like

<local:MyTag x:Key="foo" MyAttr="foo" />
熊抱啵儿 2024-08-19 17:44:18
<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");

这里元素“E”是根元素,因此它在架构中添加“ns1”前缀。

由于所有其他提到的元素(如“B”、“S”、“V”、“B1”)都是“E”的子元素,因此它以提到的前缀作为前缀,但再次显示架构子元素。

因此,您将获得如上所述的所需输出,其中根元素中包含架构,而子元素仅包含前缀。

<ns1:E xmlns:ns1="schema">
    <ns1:B>
       <ns2:S>
         <ns2:V>
           <ns2:Bl />
         </ns2:V>
       </ns2:S>
    </ns1:B>
</ns1:E>

So to get the output as above using Create XmlElement it could be achieved as below :

CreateElement("ns1","E", "schema");
CreateElement("ns1","B", "schema");
CreateElement("ns2","S", "schema");
CreateElement("ns2","V", "schema");
CreateElement("ns2","B1", "schema");

Here Element "E" is the root element so it prefixes it with "ns1" along with the schema.

Since all the other mentioned Elements like "B","S","V","B1" are child Elements of "E" it prefixes with the mentioned prefix but do not again displays the schema for the child Elements.

And hence you get the desired output as above with schema in the root element and only prefix for child elements.

剩余の解释 2024-08-19 17:44:18

冒号之前的单词是名称空间。如果您想要一个元素“ns1:E”,则需要创建一个名为“E”的元素并将其命名空间设置为“ns1”。

The word before the colon is the namespace. If you want to have an element "ns1:E", you needs to create an element named "E" and set its namespace to "ns1".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文