2017-11-18 16 views
1

私は構造中にいくつかのノードを持つことができ、いくつかのXMLファイルを持っている<funding-source><institution-wrap>...</institution-wrap></funding-source>私は、ノード内の値を取得します(もしあれば)と、すなわち、別のXMLファイルを使用して値を一致させたい 、funding_info.xmlのノード<skos>と一致するものがある場合は、親ノードの属性値を<skd>にしてから を入力して、メインXMLファイルの<funding-source><institution-wrap>...</institution-wrap></funding-source><funding-source><institution-wrap>...</institution-wrap><fundref-id>The attribute value found</fundref-id></funding-source>に置き換えます。私は変更するXMLファイルは簡単なXMLファイル修正プログラムの作成に問題がありますか?

<funding-source><institution-wrap>NSF</institution-wrap></funding-source> 
<funding-source><institution-wrap>Caltech</institution-wrap></funding-source> 
<funding-source><institution-wrap>Massachusetts Institute of Technology, USA</institution-wrap></funding-source> 

のようないくつかのノードが出力

<funding-source><institution-wrap>NSF</institution-wrap><fundref-id>10.1.3169</fundref-id></funding-source> 
<funding-source><institution-wrap>Caltech</institution-wrap></funding-source> 
<funding-source><institution-wrap>Massachusetts Institute of Technology, USA</institution-wrap><fundref-id>10.1.4560</fundref-id></funding-source> 
する必要があります含まれている場合 funding_info.xmlは、例えば

<?xml version="1.0" encoding="UTF-8"?> 
<item> 
    <skd id="inst/10.1.3169"> 
     <skosl> 
      <skos>NSF</skos> 
     </skosl> 
     <skosl> 
      <skos>National Science Foundation</skos> 
     </skosl> 
     <skosl> 
      <skos>Jatio Bigyan Songothon</skos> 
     </skosl> 
    </skd> 
    <skd id="inst/10.1.4560"> 
     <skosl> 
      <skos>Massachusetts Institute of Technology</skos> 
     </skosl> 
     <skosl> 
      <skos>MIT</skos> 
     </skosl> 
     <skosl> 
      <skos>Massachusetts Institute of Technology, USA</skos> 
     </skosl> 
    </skd> 
    <skd id="inst/11.2.30213"> 
     <skosl> 
      <skos>European Union</skos> 
     </skosl> 
     <skosl> 
      <skos>European Union</skos> 
     </skosl> 
     <skosl> 
      <skos>European Union FP7 Programme</skos> 
     </skosl> 
    </skd> 
</item> 

以下のようになります。

<skos>ノードにCaltechが見つからないため、funding_info.xmlの値は変更されません。 は、私はこれをアプローチするかどうかはわかりませんが、以下、私が試したものですが、スタックの途中だ

static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(@"C:\Users\Desktop\my_sample.xml", LoadOptions.PreserveWhitespace); 
      var x = doc.Descendants("funding-source").Elements("institution-wrap").Select(a => a.Value).ToArray(); 
      if (x.Any()) 
      { 
       foreach (var cont in x) 
       { 
        XDocument doc2 = XDocument.Load(@"C:\Users\Desktop\funding_info.xml", 
         LoadOptions.PreserveWhitespace); 
        var y = doc2.Descendants("skos").Ancestors("skosl").Ancestors("skd").Attributes("id") 
         .Select(a => a.Value); 
        if (doc2.Descendants("skos").Any().Value(cont)) 
        { 
         var y = doc2.Descendants("skos").Ancestors("skosl").Ancestors("skd").Attributes("id") 
          .Select(a => a.Value).First(); 
............. ................... 
............. ..................       

        } 
       } 
      } 


      Console.ReadLine(); 
     } 

答えて

1

読むあなたfunding_info.xmlファイルと機関名とSKDのID間のマッピングを作成します。そしてそれを使って、すべての資金調達元の要素を調べて、既にIDを持っているかどうかを確認することができます。そうでない場合は、そのマッピングを調べて、既知の値があるかどうかを確認します。存在する場合は、IDを追加します。

var fundingDoc = XDocument.Load(pathToFundingInfo); 
// creating a lookup since there are multiple instances of the institutions 
var skdIds = fundingDoc.Descendants("skd").Elements("skosl") 
    .ToLookup(s => (string)s.Element("skos"), s => (string)s.Parent.Attribute("id")); 
var outDoc = XDocument.Load(pathToUpdatedFile); 
foreach (var f in outDoc.Descendants("funding-source")) 
{ 
    if (f.Element("fundref-id") == null) 
    { 
     var name = (string)f.Element("institution-wrap"); 
     var skd = skdIds[name].FirstOrDefault(); // just take the first one 
     if (skd != null) 
      f.Add(new XElement("fundref-id", skd.Substring("inst/".Length))); 
    } 
} 
outDoc.Save(pathToUpdatedFile); 

これは、このような出力を生成する必要があります

<root> 
    <funding-source> 
    <institution-wrap>NSF</institution-wrap> 
    <fundref-id>10.1.3169</fundref-id> 
    </funding-source> 
    <funding-source> 
    <institution-wrap>Caltech</institution-wrap> 
    </funding-source> 
    <funding-source> 
    <institution-wrap>Massachusetts Institute of Technology, USA</institution-wrap> 
    <fundref-id>10.1.4560</fundref-id> 
    </funding-source> 
</root> 

あなたは、これは大文字と小文字を区別しないようにしたい場合は、すべて大文字または小文字のルックアップの鍵を作ります。

// ... 
var skdIds = fundingDoc.Descendants("skd").Elements("skosl") 
    .ToLookup(s => s.Element("skos").Value.ToUpperInvariant(), s => (string)s.Parent.Attribute("id")); 
// ... 
     var name = f.Element("institution-wrap").Value.ToUpperInvariant(); 
// ... 
+0

「引数1:「文字列」から「System.IO.Stream」を「outDoc.Save」部分に変換できません。 – Bumba

+0

うーん、それはうまくいくはずです。これは 'XDocument'のメソッドです。 ['XDocument.Save(string)'](https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument.save?view=netframework-4.7.1#System_Xml_Linq_XDocument_Save_System_String_) –

+0

まあ、それはシャープデベロップメントで動作しますが、ビジュアルスタジオではありません....奇妙な?ところで、検索で大文字小文字を区別しないようにするにはどうすればよいですか? – Bumba

関連する問題