2014-08-29 119 views
0

我有這樣的xml字符串,我試圖將它反序列化爲一個具有類Credentials的對象。但命名空間前綴正在阻止我。如何從XElement中刪除名稱空間前綴(C#)?

Credentials類本身沒有任何XmlRoot屬性來設置命名空間。但是一些包含Credentials屬性的類可以。下面的「ds」前綴來自容器的序列化xml。

容器的XML是這樣的:

<ds:DataSource xmlns:ds="urn:My-Namespace"> 
    <ds:Credentials> 
     <ds:UserName>foo</ds:UserName> 
     <ds:Domain>bar</ds:Domain> 
    </ds:Credentials> 
</ds:DataSource>" 

然後,當我從containter元素的元素「憑證」,它返回:

<ds:Credentials xmlns:ds="urn:My-Namespace"> 
    <ds:UserName>foo</ds:UserName> 
    <ds:Domain>bar</ds:Domain> 
</ds:Credentials> 

我不能把這反序列化一個正確的Credentials對象,因爲額外的名稱空間。是否有可能將其刪除?我試過How to remove namespace prefix. (C#),元素仍然有一個默認的名稱空間。

<Credentials xmlns="urn:My-Namespace"> 
    <UserName>foo</UserName> 
    <Domain>bar</Domain> 
</Credentials> 

回答

0

感謝har07和http://bohu7.wordpress.com/2008/12/11/removing-default-namespaces-from-an-xdocument/的靈感,我摸索出瞭解決方案自己,它將繼續正常的屬性和刪除其他命名空間:

public static void RemoveNamespace(this XElement element) 
    { 
     foreach (XElement e in element.DescendantsAndSelf()) 
     { 
      if (e.Name.Namespace != XNamespace.None) 
       e.Name = e.Name.LocalName; 

      if (e.Attributes().Any(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None)) 
       e.ReplaceAttributes(e.Attributes().Select(NoNamespaceAttribute)); 
     } 
    } 

    private static XAttribute NoNamespaceAttribute(XAttribute attribute) 
    { 
     return attribute.IsNamespaceDeclaration 
      ? null 
      : attribute.Name.Namespace != XNamespace.None 
       ? new XAttribute(attribute.Name.LocalName, attribute.Value) 
       : attribute; 
    } 
1

有一個在MSDN的文章,可適應你想要做什麼:How to: Change the Namespace for an Entire XML Tree

基本上文章建議在樹改變的每一個XElementName到一個新的Name(僅供參考,Name財產包含有關名稱空間和本地名稱的信息)。在此情況下,因爲我們希望每一個元素變成沒有命名空間,你可以改變Name到相應的Name.LocalName

var xml = @"<ds:DataSource xmlns:ds=""urn:My-Namespace""> 
    <ds:Credentials> 
     <ds:UserName>foo</ds:UserName> 
     <ds:Domain>bar</ds:Domain> 
    </ds:Credentials> 
</ds:DataSource>"; 
var tree1 = XElement.Parse(xml); 
foreach (XElement el in tree1.DescendantsAndSelf()) 
{ 
    el.Name = el.Name.LocalName; 
    List<XAttribute> atList = el.Attributes().ToList(); 
    el.Attributes().Remove(); 
    foreach (XAttribute at in atList) 
     el.Add(new XAttribute(at.Name.LocalName, at.Value)); 
} 
//remove xmlns:ds="urn:My-Namespace" 
tree1.RemoveAttributes(); 
//print result to console 
Console.WriteLine(tree1.ToString()); 
+0

謝謝,代碼似乎會刪除所有元素的所有屬性,包括不是命名空間的屬性。 – bigbearzhu 2014-08-31 22:40:39

+0

是的,我試圖不要過度複雜的解決方案,因爲發佈的示例沒有除命名空間前綴屬性以外的任何屬性。無論如何,很高興看到你自己提出瞭解決方案 – har07 2014-09-01 01:50:54