2

これは多くの人が持つクエリのように聞こえますが、何時間も検索した後でも、この問題に対処する質問を見つけることさえできません.

LINQ2Xml クラスを使用して XML ドキュメントを生成しています。私は多くの名前空間を使用しており、ノードは動的に作成されるため、素敵な new XElement("abc",new XElement...)) 形式を使用して宣言することはできません。

次に例を示します。

XNamespace ns1 = "scheme://ns1";
XNamespace ns2 = "scheme://ns2";
XNamespace ns3 = "scheme://ns3";
XNamespace ns4 = "scheme://ns4";

XElement el1 = new XElement(ns1 + "el1");
XElement el2 = new XElement(ns2 + "el2");
XElement el3 = new XElement(ns3 + "el3");
XElement el4 = new XElement(ns4 + "el4");

XElement el5 = new XElement(ns1 + "el5");
XElement el6 = new XElement(ns1 + "el5");
XElement el7 = new XElement(ns1 + "el5");

el4.Add(el7);
el3.Add(el6);
el2.Add(el5);

el1.Add(el2);
el1.Add(el3);
el1.Add(el4);

XDocument doc = new XDocument(el1);
Debug.Write(doc.ToString());

上記のコードは、次の出力を生成します。

<el1 xmlns="scheme://ns1">
  <el2 xmlns="scheme://ns2">
    <el5 xmlns="scheme://ns1" />
  </el2>
  <el3 xmlns="scheme://ns3">
    <el5 xmlns="scheme://ns1" />
  </el3>
  <el4 xmlns="scheme://ns4">
    <el5 xmlns="scheme://ns1" />
  </el4>
</el1>

一方、すべてのネームスペース宣言がすべての要素ではなく上部にある次の (E&OE) に似た出力が必要です。

<el1 xmlns="scheme://ns1" xmlns:ns2="scheme://ns2" xmlns:ns3="scheme://ns3" xmlns:ns4="scheme://ns4">
    <ns2:el2 >
        <ns1:el5 />
    </ns2:el2>
    ....
</el1>

私はすでに次のことを試しましたが、まったく違いはありません。

IEnumerable<XAttribute> allNs = doc.Root.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration);
int i = 0;
foreach (string uri in allNs.Select(a => a.Value).Distinct()) {
    string prefix = "ns" + ++i;
    doc.Root.Add(new XAttribute(XNamespace.Xmlns + prefix, uri));
}
Debug.Write(doc.ToString(SaveOptions.OmitDuplicateNamespaces));

理由: ファイルには、おそらく数十個の名前空間と、それぞれから数百個の要素が含まれていると予想されます。各名前空間の uri の長さはおそらく 50 文字です。名前空間を 1 回宣言するだけで、数千文字を節約できます。さらに、見栄えが良くなります。

これを行う方法を知っている人はいますか?

4

1 に答える 1