通过名称空间前缀访问名称空间

时间:2011-05-05 18:59:44

标签: xml linq-to-xml xml-namespaces

MSDN

  

使用LINQ的优势之一   使用C#的XML是您不必的   使用XML前缀。当LINQ转换为XML时   每个都加载或解析XML文档   XML前缀被解析为它   相应的XML命名空间后   当你使用文档时   你几乎使用名称空间   始终通过访问命名空间   命名空间URI,而不是通过   命名空间前缀当开发人员工作   他们使用LINQ to XML中的XML名称   始终使用完全限定的XML   name(即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;

b)为什么在Linq中通过名称空间URI访问名称空间的XML比通过名称空间前缀访问它们更好?

谢谢

修改

  

为什么您认为您的代码示例使用了   一个前缀?

我不知道为什么我认为上面的代码使用了名称空间前缀。

1)有没有办法通过前缀而不是名称空间URI访问命名空间(例如,在尝试使用XElement.Elements(Xname)方法查找子元素时)?

2)除了同一命名空间同时具有默认命名空间和附加命名空间声明的文档之外,是否还有其他任何示例我应该知道在序列化文档时输入文档中的前缀可能无法保留?

1 个答案:

答案 0 :(得分:2)

为什么您认为您的代码示例使用前缀?它使用XNamespace对象,它表示LINQ to XML对象模型和API中命名空间的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对象模型的缺点当然是不存储元素或属性节点的任何前缀,在这种情况下,加载和保存时输入文档中的前缀可能不会被保留。