2010-12-02 2 views
11

저는 Linq를 XML에 사용하여 새 XML 파일을 만듭니다. 파일의 일부분은 기존 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 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 파일을하지만,

<?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는 요소와 동일한 네임 스페이스에 지금

<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> 

입니다. 이것은 본질적으로 빠르며 더러운 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; 
} 
관련 문제