Как получить доступ к атрибуту родительского узла с помощью поставщика XML-типов F# Data?
-
21-12-2019 - |
Вопрос
Как получить доступ к атрибуту родительского узла с помощью Поставщик XML-типов данных F#?Допустим, у меня есть следующий XML:
<?xml version="1.0" encoding="UTF-16"?>
<ROOT>
<level1 name="level1Name1" x="8">
<level2 name="level2Name1" a="8" b="104" />
<level2 name="level2Name2" a="85" b="140" />
</level1>
<level1 name="level1Name2" x="10">
<level2 name="level2Name3" a="50" b="500" />
<level2 name="level2Name4" a="376" b="1065" />
<level2 name="level2Name5" a="10" b="100" />
<level2 name="level2Name6" a="700" b="700" />
</level1>
<level1 name="level1Name3" x="7">
<level2 name="level2Name7" a="502" b="66" />
</level1>
</ROOT>
И я хочу использовать это в приведенном ниже коде:
open System
open System.Xml.Linq
open FSharp.Data
type myXmlType = XmlProvider<"""<?xml version="1.0" encoding="UTF-16"?><ROOT><level1 name="level1Name1" x="8"><level2 name="level2Name1" a="8" b="104" /><level2 name="level2Name2" a="85" b="140" /></level1><level1 name="level1Name2" x="10"><level2 name="level2Name3" a="50" b="500" /><level2 name="level2Name4" a="376" b="1065" /><level2 name="level2Name5" a="10" b="100" /><level2 name="level2Name6" a="700" b="700" /></level1><level1 name="level1Name3" x="7"><level2 name="level2Name7" a="502" b="66" /></level1></ROOT>""">
let myXml = myXmlType.Parse("""<?xml version="1.0" encoding="UTF-16"?><ROOT><level1 name="level1Name1" x="8"><level2 name="level2Name1" a="8" b="104" /><level2 name="level2Name2" a="85" b="140" /></level1><level1 name="level1Name2" x="10"><level2 name="level2Name3" a="50" b="500" /><level2 name="level2Name4" a="376" b="1065" /><level2 name="level2Name5" a="10" b="100" /><level2 name="level2Name6" a="700" b="700" /></level1><level1 name="level1Name3" x="7"><level2 name="level2Name7" a="502" b="66" /></level1></ROOT>""")
let howToDoIt =
myXml.GetLevel1s()
|> Seq.collect (fun L1 -> L1.GetLevel2s())
|> Seq.tryFind (fun L2 -> L2.b = L1.x * L2.a) // *REMARK
|> function
| None -> ""
| Some L2 -> L2.Name
*замечание:L1.x, очевидно, не сработает, но я хочу добиться чего-то подобного.
Решение
Я думаю, что самым простым способом было бы использовать Seq.tryPick
на L1
s, с внутренней функцией поиска среди дочерних элементов текущего L1
:
myXml.GetLevel1s()
|> Seq.tryPick (fun L1 ->
L1.GetLevel2s()
|> Seq.tryFind (fun L2 -> L2.b = L1.x * L2.a))
|> function
| None -> ""
| Some L2 -> L2.Name
Не связан с StackOverflow