2015-12-14 3 views
1

в образце XML-файла для поставщика типа F # -DATA, у меня есть элементы, которые не являются обязательными, как так:Fsharp.Data: Дополнительные элементы в XML

<RootElement> 
    <MandatoryElement> ... </MandatoryElement> 
    <OptionalElement> ... </OptionalElement> 
    <AnotherElement> ... </AnotherElement> 
</RootElement> 

Я не знаю, как указать Необязательный элемент как необязательный. Может быть только один RootElement, поэтому я не могу добавить еще один, не имеющий опции OptionalElement. Как я могу сказать парсеру, что OptionalElement на самом деле необязательный?

ответ

0

Невозможно явно указать «необязательный» внутри самого XML. Поставщик типа XML указывает на это, если он видит элемент в некоторых местах, но не другие, но это всего лишь образованное предположение.

Для явного указания, какие элементы являются необязательными, которые могут быть краткими и т. Д., Мы имеем нечто, называемое «XML-схемой», также известное как «XSD». К сожалению, поставщик типа XML не поддерживает XSD на данный момент, хотя есть an open issue for it.

Один взломанный я могу предложить вам следующее: сделать ваш корневой элемент вложенным под другим, «супер-корневым» элементом, а затем сделать два из «реальных корневых», которые позволят поставщику типа вывести необязательно- Несс. Затем поставщик типа будет генерировать для вас «супер-корневой» тип, который вы можете безотлагательно игнорировать и использовать только вложенный корень.

Конечно, поскольку поставщик типов XML, к сожалению, не поддерживает синтаксический анализ некорневых элементов, вам также придется «обертывать» текст XML в элементе «супер-root» каждый раз, когда вы его разбираете, что ограничивает решение только небольшими документами.

type Xml = XmlProvider<""" 
    <SuperRoot> 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <OptionalElement> ... </OptionalElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement> 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement> 
    </SuperRoot> 
"""> 

let parse xml = (Xml.Parse ("<SuperRoot>" + xml + "</SuperRoot>")).RootElements.[0] 
1

Провайдер XML-типа работает, вызывая тип из образца. Вы можете предоставить более одного образец с помощью дополнительного SampleIsList аргумента:

open FSharp.Data 

type RootElement = XmlProvider<""" 
<samples> 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <OptionalElement> ... </OptionalElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement> 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement> 
</samples>""", SampleIsList = true> 

Из этого списка образцов, то XML Тип Provder делает вывод, что OptionalElement, ну ... по желанию, и типов его в качестве string option:

let x = RootElement.Parse """ 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <OptionalElement> ... </OptionalElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement>""" 
let y = RootElement.Parse """ 
    <RootElement> 
     <MandatoryElement> ... </MandatoryElement> 
     <AnotherElement> ... </AnotherElement> 
    </RootElement>""" 

Использование:

> y.OptionalElement.IsSome;; 
val it : bool = false 
> x.OptionalElement.IsSome;; 
val it : bool = true 
> x.OptionalElement |> Option.get;; 
val it : string = " ... " 
Смежные вопросы