Подтвердить что ты не робот

Имя элемента xml с двоеточием

Я работаю против стороннего 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

Это отлично работает, пока я удаляю двоеточия из имен элементов. С двоеточиями только имя правой части двоеточия находится в имени элемента. Я знаю, что двоеточия - нет-нет, но я не контролирую то, что диктует сторонняя апи.

Каковы мои возможности обойти это? Существуют ли какие-либо полезные способы принуждения двоеточий к именам элементов? Мне не нужно использовать XMLDocument, но не уверен, что другой метод получит меня там.

UPDATE: Я понимаю, что <ns1: относится к пространству имен. И да, есть 2. При написании XML я могу заставить его работать, если я скажу -

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

Однако вывод XML этого файла

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

Если я просто скажу XmlDocument.CreateElement("ns1:E"); без uri, то выход будет просто <E>. Я не хочу, чтобы на выходе была ссылка на схему, но мне нужен префикс. Результат, который я хочу достичь, просто <ns1:E>. Оба пространства имен объявлены наверху, что, я думаю, означало бы, что я должен был бы объявить их на каждом node.

4b9b3361

Ответ 2

Двоеточия указывают, что эти элементы находятся в ns1 namespace. Это необходимо, когда вы используете несколько схем. Предполагая, что в документе используется только ns1, он по существу эквивалентен отсутствию "ns1:" в этих тегах. Подробнее см. данное руководство.

Ответ 3

Документ 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 и Bl находятся в пространстве имен 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:E не имеет смысла, если префикс ns1 не сопоставляется с пространством имен, либо в этом элементе, либо в одном из его предков. (Кроме того, пространство имен не является ссылкой схемы.) Если вы используете

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

чтобы создать элемент, а затем добавить его к элементу, который уже объявил ns1 как префикс для пространства имен schema, тогда DOM добавит элемент без объявления пространства имен, поскольку в этом контексте он не требуется. Если ns1 не объявлен (или объявлен как аббревиатура некоторого пространства имен, кроме schema), тогда DOM будет прикреплять декларацию пространства имен к элементу, а также префикс.

tl; dr: Вы интересуетесь пространствами имен, а не префиксами пространства имен.

Ответ 4

<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", он префикс с указанным префиксом, но не снова отображается схема для дочерних элементов.

И, следовательно, вы получите желаемый результат, как указано выше, с помощью схемы в корневом элементе и только префикс для дочерних элементов.

Ответ 5

(Я знаю, это старый вопрос, но я делаю что-то эквивалентное и выяснил, как волновать мертвого цыпленка, чтобы он работал. Я документирую его, чтобы потом найти его.)

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

Ответ 6

Слово перед двоеточием - это пространство имен. Если вы хотите иметь элемент "ns1: E", вам нужно создать элемент с именем "E" и установить его пространство имен "ns1".