Доступ к пространствам имен через их префикс пространства имен - PullRequest
1 голос
/ 05 мая 2011

* MSDN 1002 *:

Одно из преимуществ использования LINQ для XML с C # - это то, что вам не нужно использовать префиксы XML. Когда LINQ to XML загружает или анализирует XML-документ, каждый Префикс XML разрешается в его соответствующее пространство имен XML. После что, когда вы работаете с документом который использует пространства имен, вы почти всегда получать доступ к пространствам имен через URI пространства имен, а не через префикс пространства имен. Когда работают разработчики с именами XML в LINQ to XML они всегда работать с полностью квалифицированным XML имя (то есть пространство имен XML и местное название).

a) Хм, а приведенная выше цитата утверждает, что в Linq to XML разработчики всегда работают с полностью определенными именами XML и, таким образом, всегда получают доступ к пространствам имен через свой URI пространства имен, а не через префикс пространства имен?

Но следующий код не получает доступ к пространству имен через префикс, а не к URI пространства имен (и мы не можем также утверждать, что в этом примере мы не работаем с полностью определенным именем XML):

XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> c1 =
    from el in root.Elements(aw + "Child")
    select el;

б) почему в Linq to XML доступ к пространствам имен через URI пространства имен предпочтительнее, чем доступ к ним через префикс пространства имен?

спасибо

EDIT:

Почему вы думаете, что ваш пример кода использует префикс?

Понятия не имею, почему я думал, что в приведенном выше коде используется префикс пространства имен.

1) есть ли способ получить доступ к пространству имен через префикс, а не URI пространства имен (например, при попытке найти дочерние элементы с помощью метода XElement.Elements(Xname))?

2) Помимо документа, имеющего как пространство имен по умолчанию, так и дополнительное объявление пространства имен для того же пространства имен, есть ли другие примеры, о которых мне следует знать, где префиксы во входном документе могут не сохраняться, когда документ сериализуется обратно?

1 Ответ

2 голосов
/ 06 мая 2011

Как вы думаете, почему в вашем примере кода используется префикс? Он использует объект XNamespace, представляющий концепцию XML пространства имен в объектной модели и API LINQ to XML. Конечно, для простоты кода XNamespace хранится в переменной с коротким именем, и эта переменная используется для создания XName в качестве аргумента метода Elements, но я не вижу, как используется какой-либо префикс или как код в любом случае зависит от использования префиксов при вводе XML. Это ответ на часть а) вашего вопроса?

Что касается части b), то, что семантически имеет значение в XML с пространствами имен, это пространство имен, к которому принадлежит элемент или атрибут, префиксы не имеют значения. Так что семантически не имеет значения, пишете ли вы

<root xmlns="http://example.com/ns1">
  <foo>bar</foo>
</root>

или

<pf1:root xmlns:pf1="http://example.com/ns1">
  <pf1:foo>bar</pf1:foo>
</pf1:root>

или

<pf2:root xmlns:pf2="http://example.com/ns1">
  <pf2:foo>bar</pf2:foo>
</pf2:root>

И выбор любых узлов элементов в этих трех примерах с LINQ to XML одинаков для всех трех примерах, вы просто определяете объект XNamespace

XNamespace ns1 = "http://example.com/ns1";

и затем вы можете использовать, например, Descendants(ns1 + "foo") для доступа к элементам с локальным именем foo в пространстве имен http://example.com/ns1.

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

Несомненно, в LINQ to XML есть префикс «незнание» недостатков, например, если у вас есть документ с пространством имен по умолчанию, но с дополнительным объявлением пространства имен для того же пространства имен, то порядок объявления пространства имен, кажется, определяет, как LINQ to XML сериализует документ обратно. Ниже приведен пример, демонстрирующий, что:

Если у нас есть два входных документа X (HT) ML XMLFile1.xml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>Example</h1>
  </body>
</html>

и XMLFile2.xml

<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>Example</h1>
  </body>
</html>

тогда вывод с VS 2010 / .NET 4.0 будет

<?xml version="1.0" encoding="ibm850"?>
<xhtml:html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en">
  <xhtml:head>
    <xhtml:title>Example</xhtml:title>
  </xhtml:head>
  <xhtml:body>
    <xhtml:h1>Example</xhtml:h1>
  </xhtml:body>
</xhtml:html>
<?xml version="1.0" encoding="ibm850"?>
<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>Example</h1>
  </body>
</html>

Так что это, безусловно, является недостатком объектной модели LINQ to XML, которая не хранит никаких префиксов узлов элементов или атрибутов, в этом случае префиксы во входном документе могут не сохраняться при загрузке и сохранении обратно.

...