使用linq to xml基于其父标记添加属性

时间:2016-07-21 09:10:08

标签: c# xml linq

我有一个问题,我需要根据其父元素

为元素添加属性

这是我的意见:

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

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

这是我的输出

<p>
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
        <mi>n</mi>
        <mo>!</mo>
    </math>
    <MoreTag>
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
            <mi>n</mi>
            <mo>!</mo>
        </math>
    </MoreTag>
</p>

如果父标记名称为InlineEquation,则其标记名称和属性将更改为<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">

如果父标记名称为Equation,则其标记名称和属性将更改为<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline">

这是我的代码

XElement rootEquation = XElement.load("myfile.xml")
IEnumerable<XElement> equationFormat =
    from el in rootEquation.Descendants("InlineEquation ").ToList()

    select el;
foreach (XElement el in equationFormat)
{
    Console.WriteLine(el);
    //what code do i need here?
}

2 个答案:

答案 0 :(得分:1)

你需要做四件事:

  • 删除未使用的命名空间声明xmlns:xlink="..."
  • 添加显示属性
  • 重命名父元素及其后代以包含新名称空间
  • 删除父元素并替换为其子元素

所以,以InlineEquation为例:

XNamespace mathMl = "http://www.w3.org/1998/Math/MathML";

var doc = XDocument.Parse(xml);

foreach (var equation in doc.Descendants("InlineEquation").ToList())
{
    foreach (var math in equation.Elements("math"))
    {
        math.Attributes().Where(x => x.IsNamespaceDeclaration).Remove();
        math.SetAttributeValue("display", "block");

        foreach (var element in math.DescendantsAndSelf())
        {
            element.Name = mathMl + element.Name.LocalName;
        }               
    }

    equation.ReplaceWith(equation.Nodes());            
}

有关正常工作的演示,请参阅this fiddle。我将离开Equation并进行重构以删除重复内容。

答案 1 :(得分:1)

您可以直接在数学节点上工作,并检查他们的父母

XNamespace newNs= "http://www.w3.org/1998/Math/MathML";
var xDoc = XDocument.Load(<yourxml>);
var maths = xDoc.Descendants("math").ToList();

foreach (var math in maths){
    //remove old namespace (well, all attributes with this code)
    math.RemoveAttributes();

    //change the namespace
    foreach (var m in math .DescendantsAndSelf())
          m.Name = newNs + m.Name.LocalName;

    //add the display attribute depending on parent
    if (math.Parent.Name == "InlineEquation")
        math.SetAttributeValue("display", "block");

    if (math.Parent.Name == "Equation")
        math.SetAttributeValue("display", "inline");

    //replace parent node by math node
    math.Parent.ReplaceWith(newNode);
}