2016-08-24 11 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を使って値を置き換えます。実際のxmlとしてXpathを使用したいとは思いません。扱うのは非常に多くの内部ノードがあり、各属性のxpathを取得するのは難しいです。

現在のコードは置き換えに使用しています。 new.xml中(idとして命名属性の修正と)

test.xml

<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"); 
    } 

    } 
} 

結果:

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

OKイムは、コンパイルの例を作成します。

<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

関連する問題