使用linq更改特定元素的属性

时间:2016-07-21 06:45:46

标签: c# linq

我想更改特定元素和属性的值。

但我收到一个错误:

cannot convert from 'System.Xml.Linq.XNamespace' to 'System.Xml.Linq.XName'

和指向错误的ide的部分是abc

where (string)el.Attribute(abc) == ab

这是输入xml

<p>
    <math xmlns:xlink="http://www.w3.org/1999/xlink">
                    <mi>n</mi>
                    <mo>!</mo>
                  </math>
    <MoreTag><math xmlns:xlink="http://www.w3.org/1999/xlink">
                    <mi>n</mi>
                    <mo>!</mo>
                  </math></MoreTag>
</p>

这是我的代码

XDocument doc = XDocument.Load("myxml.xml");
            XNamespace ab = "http://www.w3.org/1999/xlink";
            XNamespace abc = "xmlns:xlink";
            IEnumerable<XElement> equationFormat =
                from el in doc.Descendants("math").ToList()
                where (string)el.Attribute(abc) == ab
                select el;
            foreach (XElement el in equationFormat)
            {
                Console.WriteLine(el);
            }

我改变了这个:

<math xmlns:xlink="http://www.w3.org/1999/xlink">

到此:

<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="" >

但由于错误我不能这样做。我已经在寻找解决方案了。但问题仍然是一样的

我按照msdn的教程进行操作。我错过了什么?

https://msdn.microsoft.com/en-us/library/mt693115.aspx

1 个答案:

答案 0 :(得分:1)

xlink有一部分命名空间声明。该属性的名称与XNamespace.Xmlns命名空间中的名称相同。您可以通过搜索要更改的属性来更改声明,并将值替换为新的命名空间。请注意,您必须重命名该命名空间中的任何节点或属性(您的示例未显示)。

var xmlns = XNamespace.Xmlns;
XNamespace oldNs = "http://www.w3.org/1999/xlink";
XNamespace newNs = "http://www.w3.org/1998/Math/MathML";

// change the declarations
var decls =
    from a in doc.Descendants().Attributes()
    where a.Name == xmlns + "xlink"
    select a;
foreach (var decl in decls)
    decl.Value = newNs.NamespaceName;

// change the names of existing elements
var nodes =
    from n in doc.Descendants()
    where n.Name.Namespace == oldNs
    select n;
foreach (var node in nodes)
    node.Name = newNs + node.Name.LocalName;

// don't forget the attributes as well
var attrs =
    from a in doc.Descendants().Attributes()
    where a.Name.Namespace == oldNs
    select a;
foreach (var attr in attrs.ToList())
{
    // can't change the names directly, the attributes must be replaced
    var newName = newNs + attr.Name.LocalName;
    attr.Parent.SetAttributeValue(newName, attr.Value);
    attr.Remove();
}