XML-литералы в коде VB.NET не работают с операторами #if - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть проект vb.net, который использует XML-литерал для настройки панели навигации интерфейса пользователя.Код выглядит примерно так и работает уже много лет.

Private ReadOnly _actionTreeXml As XElement =
<nodes>
    <node key="any" name="Top">
        <node key="log" name="***LOGIN***" type="everybody"></node>
        <node key="op" name="Home" ctrl="uiHomePage" type="mfg"></node>
        <node key="barcode" name="Barcode Entry" ctrl="EditMfgEntry" type="mfg"></node>
        <node key="wip" name="Work in Progress" ctrl="QueryWIP" type="mfg"></node>
        <node key="readme" name="Version Info" type="everybody"></node>
    </node>
</nodes>

Недавно мне нужно было две сборки проекта, которые немного отличаются (не хочу платить за библиотечный код для многих пользователей),Итак, у меня есть одна сборка, в которой я выбрал все инструменты пользовательского интерфейса, связанные со штрих-кодом.Это прекрасно работает везде, кроме XML-литералов, таких как

#if USE_BAR_CODE=1
<node key="barcode" name="Barcode Entry"    ctrl="EditMfgEntry" type="mfg">  </node>
#end if

Если я установлю USE_BAR_CODE в 0, я все равно получу xml-литерал внутри блока #if, но везде в моем коде, где я # if'ed использовал обычный VBИсходный код не был скомпилирован.

Это наводит меня на мысль, что процесс компиляции обрабатывает литералы xml ДО операторов #if.Я что-то пропустил?

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Может быть совсем не решением проблемы, но, как гласит пословица: «Плохой кустарник лучше открытого поля».100

Основная идея заключается в использовании узла инструкции обработки.Если элемент имеет инструкцию обработки над ним, пропустите его, в противном случае включите его.Таким образом, вы можете контролировать «инклюзивность» этого элемента.

1) Сначала создайте метод расширения:

Module XmlExtentions
    <System.Runtime.CompilerServices.Extension>
    Function Filter(root_node As IEnumerable(Of XElement)) As IEnumerable(Of XElement)
        Return root_node.First().Elements().Where(
            Function(e)
                If e.PreviousNode Is Nothing Then Return True
                Return e.PreviousNode.NodeType <> Xml.XmlNodeType.ProcessingInstruction
            End Function)
    End Function
End Module

2.Запросите наш XML:

Dim _actionTreeXml As XElement =
    <nodes>
        <node key="any" name="Top">
            <node key="log" name="***LOGIN***" type="everybody"></node>
            <node key="op" name="Home" ctrl="uiHomePage" type="mfg"></node>
            <?Skip-Element?>
            <node key="barcode" name="Barcode Entry" ctrl="EditMfgEntry" type="mfg"></node>
            <node key="wip" name="Work in Progress" ctrl="QueryWIP" type="mfg"></node>
            <node key="readme" name="Version Info" type="everybody"></node>
        </node>
    </nodes>

Dim elements = _actionTreeXml.<node>.Filter()
'// Do something...
elements.ToList().ForEach(Sub(e) Console.WriteLine(e))
0 голосов
/ 22 ноября 2018

К сожалению, нет, вы не можете использовать такие директивы в литералах.Под капотом поведение такое же, как у операторов If, Then and Else.Вы не можете поместить их непосредственно в линию так, как вы есть, вы должны обернуть блок кода, чтобы сообщить компилятору, что компилировать, а не компилировать во время выполнения, как стандартные операторы If, Then and Else.Операторы в блоке условной компиляции должны быть полными логическими операторами.Например, вы не можете условно компилировать только атрибуты литералов, функций и т. Д. *

. Ниже приведено быстрое решение: включить узел или не включать его.Это также было проверено и прекрасно работает.

#If USE_BAR_CODE = 1 Then
    Private ReadOnly _actionTreeXml As XElement = <nodes>
                                                      <node key="any" name="Top">
                                                          <node key="log" name="***LOGIN***" type="everybody"></node>
                                                          <node key="op" name="Home" ctrl="uiHomePage" type="mfg"></node>
                                                          <node key="barcode" name="Barcode Entry" ctrl="EditMfgEntry" type="mfg"></node>
                                                          <node key="wip" name="Work in Progress" ctrl="QueryWIP" type="mfg"></node>
                                                          <node key="readme" name="Version Info" type="everybody"></node>
                                                      </node>
                                                  </nodes>
#Else
    Private ReadOnly _actionTreeXml As XElement = <nodes>
                                                      <node key="any" name="Top">
                                                          <node key="log" name="***LOGIN***" type="everybody"></node>
                                                          <node key="op" name="Home" ctrl="uiHomePage" type="mfg"></node>                                                          
                                                          <node key="wip" name="Work in Progress" ctrl="QueryWIP" type="mfg"></node>
                                                          <node key="readme" name="Version Info" type="everybody"></node>
                                                      </node>
                                                  </nodes>


#End If
...