2016-08-24 82 views
0

我有一个xml,并且想要在任何地方替换属性值,我发现它的元素名称和属性名称保持不变但要替换的属性值取决于其当前值。如果在属性名称保持不变但在不同节点中属性名称保持不变的情况下如何替换xml中的属性值

原始的XML:

<Loan> 
<status="First"> 
    <report active = "True" raw_xml = "My name is abc and I am a doctor"/> 
</status> 
<status="Second"> 
    <report active = "True" raw_xml = "My name is def and I am an actor"/> 
</status> 
<status="Third"> 
    <report active = "True" raw_xml = "My name is xyz and I am a coder"/> 
</status> 
</Loan> 

所要的输出是:

<Loan> 
<status="First"> 
    <report active = "True" raw_xml = "My doctor"/> 
</status> 
<status="Second"> 
    <report active = "True" raw_xml = "My actor"/> 
</status> 
<status="Third"> 
    <report active = "True" raw_xml = "My coder"/> 
</status> 
</Loan> 

我做一些操作来提取raw_xml的一部分,并取代其目前的价值。

我有代码如何提取和替换值。

,但由于我使用的是单一的方法/默认情况下它与错误而失败

序列包含一个以上的匹配元素

如何获得通过,并遍历每个它并使用Xdocument.descendants替换值..我不想使用Xpath作为真正的XML我正在处理有这么多的内部节点,并获得每个属性的xpath是非常艰难的。

我用于替换的当前代码。

foreach (var report in doc.Descendants("report")) 
{ 
    var xms = ""; 

    xms = report.Attribute("raw_xml").Value; 

    //My code to change to extract the required attribute value goes here..creating an xmsdoc variable and storing the output value for attribute in it 

    var element = doc.Descendants("report").Single(x => x.Attribute("active").Value == "True"); 
    element.SetAttributeValue("raw_xml", xmsdoc.ToString()); 
} 
+0

XML是大小写敏感的,从“报告”如此更改为后代“报告”。 – jdweng

+0

哎呀,是啊其实际报告..我输错了这里 – HadoopAddict

回答

1

确定即时创建可编译例如:

test.xml(具有命名为id属性修复)

<Loan> 
    <status id="First"> 
    <report active = "True" raw_xml = "My name is abc and I am a doctor"/> 
    </status> 
    <status id="Second"> 
    <report active = "True" raw_xml = "My name is def and I am an actor"/> 
    </status> 
    <status id="Third"> 
    <report active = "True" raw_xml = "My name is xyz and I am a coder"/> 
    </status> 
</Loan> 

的Program.cs

using System.Xml.Linq; 

namespace ConsoleApplication99 
{ 
    class Program 
    { 
    static string FixXmlString(string value) 
    { 
     int namePos = value.IndexOf(" name "); 
     if (namePos < 0) return value; // name not found 
     int lastSpace = value.LastIndexOf(' '); 

     int cutLength = lastSpace - namePos; 

     return value.Remove(namePos, cutLength); 
    } 

    static void Main() 
    { 
     XDocument doc = XDocument.Load("test.xml"); 

     foreach (XElement x in doc.Descendants("report").Where(x => x.Attribute("active").Value == "True")) 
     { 
     var attribute = x.Attribute("raw_xml"); 

     if (attribute != null) 
     { 
      attribute.Value = FixXmlString(attribute.Value); 
     } 
     } 

     doc.Save("new.xml"); 
    } 

    } 
} 

结果new.xml

<Loan> 
    <status id="First"> 
    <report active="True" raw_xml="My doctor" /> 
    </status> 
    <status id="Second"> 
    <report active="True" raw_xml="My actor" /> 
    </status> 
    <status id="Third"> 
    <report active="True" raw_xml="My coder" /> 
    </status> 
</Loan> 

编辑:添加缺少的“主动”检查

+0

这个想法已经为我实施我的真正的XML。但是将属性值设置为字符串类型,我的xml的大小从300 kb增加到1254 kb。任何想法如何解决这个问题? – HadoopAddict

+0

没问题,很棒!使用这个想法来解决我的其他问题http://stackoverflow.com/questions/38960338/how-to-remove-nodes-in-an-xml-that-is-inside-another-xml – HadoopAddict

相关问题