Пространство имен XElement по умолчанию для атрибутов обеспечивает непредвиденное поведение - PullRequest
3 голосов
/ 05 августа 2009

У меня проблемы с созданием документа XML, который содержит пространство имен по умолчанию и именованное пространство имен, трудно объяснить, просто показать, что я пытаюсь создать ...

<Root xmlns="http://www.adventure-works.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.SomeLocatation.Com/MySchemaDoc.xsd">
  <Book title="Enders Game" author="Orson Scott Card" />
  <Book title="I Robot" author="Isaac Asimov" />
</Root>

но в итоге я получаю вот это ...

<Root xmlns="http://www.adventure-works.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.SomeLocatation.Com/MySchemaDoc.xsd">
  <Book p3:title="Enders Game" p3:author="Orson Scott Card" xmlns:p3="http://www.adventure-works.com" />
  <Book p3:title="I Robot" p3:author="Isaac Asimov" xmlns:p3="http://www.adventure-works.com" />
</Root>

Код, который я написал для создания этого фрагмента XML, выглядит так ...

  XNamespace aw = "http://www.adventure-works.com";
  XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
  XElement root = new XElement(aw + "Root",
      new XAttribute("xmlns", "http://www.adventure-works.com"),
      new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
      new XAttribute(xsi + "SchemaLocation", "http://www.SomeLocatation.Com/MySchemaDoc.xsd"),

      new XElement(aw + "Book",
        new XAttribute(aw + "title", "Enders Game"),
        new XAttribute(aw + "author", "Orson Scott Card")),
      new XElement(aw + "Book",
        new XAttribute(aw + "title", "I Robot"),
        new XAttribute(aw + "author", "Isaac Asimov")));

на основе примера на MSDN

**** ***** EDIT 1014 *

Хорошо, проведя еще несколько экспериментов, я теперь очень озадачен тем, как работают пространства имен XML ...

если я удалю атрибут aw + theattrate, я получу то, что мне было нужно ... но теперь кажется, что то, что я преследовал, на самом деле не то, что я ожидал Я думал, что пространства имен были унаследованы от их родителей, разве это не верно и для атрибутов? потому что этот код для чтения атрибутов не работает, как я ожидал ...

  XElement xe = XElement.Parse(textBox1.Text);
  XNamespace aw = "http://www.adventure-works.com";
  var qry = from x in xe.Descendants(aw + "Book")
            select (string)x.Attribute(aw + "author");

Однако, если я удалю aw + для атрибута, все в порядке, что заставляет меня предположить, что я не могу иметь атрибуты в пространстве имен по умолчанию. Это правильно?

Ответы [ 2 ]

6 голосов
/ 05 августа 2009

Хороший вопрос. Я немного покопался и нашел этот бит спецификации XML :

Объявление пространства имен по умолчанию относится ко всем элементам без префиксов имена в пределах своей области. По умолчанию декларации пространства имен не применяются непосредственно к именам атрибутов; интерпретация без префикса атрибуты определяется элемент, на котором они появляются.

Позже приведем пример:

Например, каждый из неверных тегов пустого элемента недопустим в следующих случаях:

<!-- http://www.w3.org is bound to n1 and n2 -->
<x xmlns:n1="http://www.w3.org" 
   xmlns:n2="http://www.w3.org" >
  <bad a="1"     a="2" />
  <bad n1:a="1"  n2:a="2" />
</x>

Однако каждое из следующих утверждений допустимо, второе, поскольку пространство имен по умолчанию> не применяется к именам атрибутов:

<!-- http://www.w3.org is bound to n1 and is the default -->
<x xmlns:n1="http://www.w3.org" 
   xmlns="http://www.w3.org" >
  <good a="1"     b="2" />
  <good a="1"     n1:a="2" />
</x>

По сути, похоже, что имена атрибутов не получают пространства имен по умолчанию, что объясняет все, что вы видели:)

1 голос
/ 28 ноября 2011
XElement doc = XElement.Parse(ToXml());
doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
var ele = doc.DescendantsAndSelf();
foreach (var el in ele)
    el.Name = ns != null ? ns + el.Name.LocalName : el.Name.LocalName;

Для всех, кто потратил 2 дня, пытаясь найти ответ.

...