0

実行する必要のあるユーティリティジョブの1つにF#を使用しようとしています。

xml構成ファイルを含むディレクトリから、検索対象の属性を持つ特定のノードを含むすべてのファイルを識別し、一致するものを見つけたら、同じファイルに兄弟ノードを挿入したいと思います。すべてのファイルを識別するためのスニペットを作成しました。これで、属性を繰り返して検索し、必要に応じて追加する一連のファイルができました。

open System.Xml.Linq

let byElementName elementToSearch = XName.Get(elementToSearch)

let xmlDoc = XDocument.Load(@"C:\\Some.xml")
xmlDoc.Descendants <| byElementName "Elem"
|> Seq.collect(fun(riskElem) -> riskElem.Attributes <| byElementName "type" )
|> Seq.filter(fun(pvAttrib) -> pvAttrib.Value = "abc")
|> Seq.map(fun(pvAttrib) -> pvAttrib.Parent)
|> Seq.iter(printfn "%A")

私がやりたいのは、最後のprintfの代わりに、このタイプの別のノードを追加することです"Elem"type = "abc2"

    <Product name="Node" inheritsfrom="Base">
      <SupportedElems>
        <Elem type="abc" methodology="abcmeth" />
        <Elem type="def" methodology="defmeth" />
</SupportedElems>
</Product>

結果XML:

<Product name="Node" inheritsfrom="Base">
  <SupportedElems>
    <Elem type="abc" methodology="abcmeth" />
    <Elem type="abc2" methodology="abcmeth" /> <!-- NEW ROW TO BE ADDED HERE -->
    <Elem type="def" methodology="defmeth" />

4

2 に答える 2

3

私の意見では、複雑なLINQ to XMLクエリは不器用であり、XPathを使用した方が適切です。

open System.Xml.Linq
open System.Xml.XPath

xmlDoc.XPathEvaluate("//Elem[@type='abc']") :?> _
|> Seq.cast<XElement>
|> Seq.iter (fun el -> 
  el.AddAfterSelf(XElement.Parse(@"<Elem type=""abc2"" methodology=""abcmeth""/>")))

その後のXMLドキュメント:

<Product name="Node" inheritsfrom="Base">
  <SupportedElems>
    <Elem type="abc" methodology="abcmeth" />
    <Elem type="abc2" methodology="abcmeth" />
    <Elem type="def" methodology="defmeth" />
  </SupportedElems>
</Product>
于 2012-07-16T15:49:53.080 に答える
1

関数はファイルから要素を正しく検出しElemますが、何も出力しません。elem.Value印刷しているプロパティは、要素の本体を参照していますが、この場合は空です次の入力を使用すると、「1」と「2」が出力されます。

<Product name="Node" inheritsfrom="Base"> 
  <SupportedElems> 
    <Elem type="abc" methodology="abcmeth">one</Elem>
    <Elem type="def" methodology="defmeth">two</Elem>
  </SupportedElems> 
</Product>

次のように、要素全体(本文だけでなく)を印刷できます。

let pvElement (configFile : string) =  
  let xmlDoc = XDocument.Parse configFile 
  xmlDoc.Descendants(byElementName "Elem")
  |> Seq.iter (printfn "%A") 

特定の要素(特定の属性を持つ)を選択し、その要素が見つかった場合に何かを実行する場合は、おそらくSeq.tryPick関数を使用できますが、それは別の質問になります。

于 2012-07-16T12:56:21.810 に答える