首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用F#搜索元素,然后添加同级节点

使用F#搜索元素,然后添加同级节点
EN

Stack Overflow用户
提问于 2012-07-16 11:46:54
回答 2查看 625关注 0票数 0

我试图将F#用于我需要运行的实用程序作业之一。

从包含xml配置文件的目录中,我希望标识包含有属性正在查找的特定节点的所有文件,并且在找到匹配时,我希望在同一个文件中插入一个同级节点。我已经编写了识别所有文件的片段,现在我有了一个文件序列,我想迭代这些文件,并在必要时搜索属性并追加。

代码语言:javascript
复制
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"类型的节点。

代码语言:javascript
复制
    <Product name="Node" inheritsfrom="Base">
      <SupportedElems>
        <Elem type="abc" methodology="abcmeth" />
        <Elem type="def" methodology="defmeth" />
</SupportedElems>
</Product>

结果XML:

代码语言:javascript
复制
<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" />
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-16 15:49:53

在我看来,复杂的LINQ查询很笨拙,最好使用XPath:

代码语言:javascript
复制
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文档之后:

代码语言:javascript
复制
<Product name="Node" inheritsfrom="Base">
  <SupportedElems>
    <Elem type="abc" methodology="abcmeth" />
    <Elem type="abc2" methodology="abcmeth" />
    <Elem type="def" methodology="defmeth" />
  </SupportedElems>
</Product>
票数 3
EN

Stack Overflow用户

发布于 2012-07-16 12:56:21

您的函数正确地从文件中找到了Elem元素,但是它没有打印任何内容。正在打印的elem.Value属性引用元素的主体,在您的情况下它是空的。如果使用以下输入,则会打印“一”和“二”:

代码语言:javascript
复制
<Product name="Node" inheritsfrom="Base"> 
  <SupportedElems> 
    <Elem type="abc" methodology="abcmeth">one</Elem>
    <Elem type="def" methodology="defmeth">two</Elem>
  </SupportedElems> 
</Product>

您可以像这样打印整个元素(而不仅仅是主体):

代码语言:javascript
复制
let pvElement (configFile : string) =  
  let xmlDoc = XDocument.Parse configFile 
  xmlDoc.Descendants(byElementName "Elem")
  |> Seq.iter (printfn "%A") 

如果您想要选择一个特定的元素(带有一些指定的属性),然后如果找到了该元素,您可能可以使用Seq.tryPick函数,但这将是一个单独的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11503610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档