2010-12-02 13 views
11

私は新しいXMLファイルを作成するためにXMLにLinqを使用しています。ファイルの一部は、既存のXMLファイルから取得します。私はこれに次のコードを使用します。XElementがxmlnsを追加しました

var v2 = new XDocument(
    new XDeclaration("1.0", "utf-16", ""), 
    new XComment(string.Format("Converted from version 1. Date: {0}", DateTime.Now)), 
    new XElement(ns + "keyem", 
    new XAttribute(XNamespace.Xmlns + "xsd", xsd.NamespaceName), 
    new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), 
    new XAttribute(xsi + "schemaLocation", schemaLocation.NamespaceName), 
    new XAttribute("version", "2"), 
    new XAttribute("description", description), 
    new XElement(ns + "layout", 
     new XAttribute("type", type), 
     new XAttribute("height", height), 
     new XAttribute("width", width), 
     settings.Root)  // XML from an existing file 

問題は、xmlns = ""既存のファイルの最初の要素を追加することです。

結果は次のとおりです。私はこのようになりますから、読んでいるXMLファイル

<?xml version="1.0" encoding="utf-16"?> 
<foo 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema.xsd" 
    xmlns="http://tempuri.org/KeyEmFileSchema.xsd"> 
    <settings xmlns=""> 
     ... 
    </settings> 
</foo> 

、しかし、あなたが設定要素ので、これを見ている

<?xml version="1.0" encoding="utf-16"?> 
<settings> 
    <colormaps> 
    <colormap color="Gray"  textcolor="Black"/> 
    <colormap color="DarkGray" textcolor="White"/> 
    <colormap color="Black" textcolor="White"/> 
    <colormap color="Cyan"  textcolor="Black"/> 
    </colormaps> 
    <macromaps> 
    <macromap pattern="^@([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{ESC}$1{ESC}$2{MOUSERESET}"/> 
    <macromap pattern="^\$([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1{ESC}$2{MOUSERESET}"/> 
    <macromap pattern="^\$([0-9A-F]{2})$"    replace="{USERCLICK}{ESC}$1"/> 
    </macromaps> 
    <keydefault color="Cyan"/> 
    <groupdefault color="DarkGray"/> 
</settings> 

答えて

11

を必要に応じて、私はそれを変更することができます(おそらくあなたの文書からのものです)はこの名前空間には存在しません。これはデフォルト/ null-uri名前空間に存在します。

入力ドキュメントを変更して名前空間を変更する必要があります。

このやや単純化した例では、あなたのxmlファイルと場所は、別の文書にそれを取るしかし、それはそうする前に、それはあなたのターゲット文書のそれにそのXMLファイル内のすべての要素の名前空間を変更...

static void ProcessXmlFile() 
    { 
     XNamespace ns = "http://tempuri.org/KeyEmFileSchema.xsd/"; 

     // load the xml document 
     XElement settings = XElement.Load("data.xml"); 

     // shift ALL elements in the settings document into the target namespace 
     foreach (XElement e in settings.DescendantsAndSelf()) 
     { 
      e.Name = ns + e.Name.LocalName; 
     } 

     // write the output document 
     var file = new XDocument(new XElement(ns + "foo", 
             settings)); 

     Console.Write(file.ToString());    
    } 

この結果...

<foo xmlns="http://tempuri.org/KeyEmFileSchema.xsd/"> 
    <settings> 
    <colormaps> 
     <colormap color="Gray" textcolor="Black" /> 
     <colormap color="DarkGray" textcolor="White" /> 
     <colormap color="Black" textcolor="White" /> 
     <colormap color="Cyan" textcolor="Black" /> 
    </colormaps> 
    <macromaps> 
     <macromap pattern="^@([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{ESC}$1{ESC}$2{MOUSERESET}" /> 
     <macromap pattern="^\$([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1{ESC}$2{MOUSERESET}" /> 
     <macromap pattern="^\$([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1" /> 
    </macromaps> 
    <keydefault color="Cyan" /> 
    <groupdefault color="DarkGray" /> 
    </settings> 
</foo> 

あなたが見ることができるように、設定要素は、foo要素と同じ名前空間になりました。これは基本的には素早く汚れたXML変換ですが、インポートしているXMLドキュメント内の名前空間を尊重するものではありません。しかし、これはあなたが後になったものかもしれないし、少なくとももっと頑強なものの基礎を形成しているかもしれません。

+0

私はそれをどう理解していますか? 私は試しましたdefaultSettings.Name = ns + defaultSettings.Name.LocalName; しかし、私はそれをすべてのサブ要素について行う必要があります。もっと良いものでなければなりません。 – magol

+0

Xslt技術を使用してドキュメントを変換するか、各要素を読み込んでコード内で変換する必要があります。基本的には、ロードしたXDocumentはその文書の各要素の名前空間を知っていて、fooと同じ名前空間ではないことを知っています。 –

+0

読み込んだxmlファイルを正しい名前空間にするために変更することはできますか? – magol

1

あなたはこれのための拡張メソッドを書くことができます。 このメソッドには戻り値があり、連鎖をサポートするだけでなく、オリジナルの変換を変更して割り当てなしで使用できるようにします。

public static XElement EnsureNamespaceExists(this XElement xElement, XNamespace xNamespace) 
{ 
    string nodeName = xElement.Name.LocalName; 

    if (!xElement.HasAttribute("xmlns")) 
    { 
     foreach (XElement tmpElement in xElement.DescendantsAndSelf()) 
     { 
      tmpElement.Name = xNamespace + tmpElement.Name.LocalName; 
     } 
     xElement = new XElement(xNamespace + nodeName, xElement.FirstNode); 
    } 

    return xElement; 
} 
関連する問題