属性のXElementデフォルト名前空間は予期しない動作を提供します
-
22-07-2019 - |
質問
デフォルトの名前空間と名前付きの名前空間を含む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")));
に基づく
****編集****
OK、もう少し実験して、XML名前空間がどのように機能するかについて非常に混乱しています...
aw + theattributeを削除すると、自分が求めていたものが得られます...しかし、今では、求めていたものは実際には期待したものではないようです。名前空間は親から継承されていると思いましたが、これは属性にも当てはまりませんか?なぜなら、属性を読み取るためのこのコードは期待どおりに機能しないからです...
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 +を削除しても大丈夫なので、デフォルトのネームスペースに属性を設定できないと思い込んでしまいます。これは正しいですか?
解決
良い質問です。少し掘り下げてみると、この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>
ただし、次のそれぞれは有効です。2番目はデフォルトのネームスペースが&gt;でないためです。属性名に適用:
<!-- 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>
したがって、基本的に、属性名はデフォルトで名前空間を取得しないように見えます。
他のヒント
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日間を費やした他の人のために。