'xmlns:xsi'是重复的属性名称

时间:2016-08-30 14:57:37

标签: c# .net xml wpf xaml

我正在尝试编写一个xml编辑器,其中可以加载,编辑特定的xml文件,然后保存以供进一步使用。所以不能改变xml文件的结构。

我正在尝试遵循此Stackoverflow question,但保存XML命令在写回文件时给出了异常。我收到此错误

enter image description here

表示我有一个重复的属性名称,而我从文件加载并且没有对该文件进行任何更改。

XML文件结构:

 <?xml version="1.0" encoding="utf-8"?>
<interlocking xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <signals>
    <signal ref="SignalRef_1">
      <aspectSpeedDependencies>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
      </aspectSpeedDependencies>
    </signal>
    <signal ref="SignalRef_1">
      <aspectSpeedDependencies>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
        <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
          <targetRef ref="TargetRef" />
        </aspectSpeedDependency>
      </aspectSpeedDependencies>
    </signal>
  </signals>
  <routes>
    <route id="1">
      <start>
        <signalRef ref="pro.Routes.Route.Start.SignalRef.Ref" />
      </start>
      <target>
        <signalRef ref="Target.SingalRef" />
      </target>
      <elements>
        <switchRef>
          <switch ref="Ref" course="Left" />
        </switchRef>
        <levelcrossingRef>
          <levelcrossing ref="Ref" beam="Beam" />
          <levelcrossing ref="Ref" beam="Beam" />
          <levelcrossing ref="Ref" beam="Beam" />
        </levelcrossingRef>
        <trainDetectorRef>
          <trackCircuitBorder ref="Ref" />
          <trackCircuitBorder ref="Ref" />
          <trackCircuitBorder ref="Ref" />
        </trainDetectorRef>
      </elements>
      <flankElements>Flank</flankElements>
      <routePriority rank="1" />
    </route>
  </routes>
</interlocking>

代码背后

      using System;
        using System.Collections.Generic;
        using System.Diagnostics;
        using System.IO;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Data;
        using System.Windows.Documents;
        using System.Windows.Input;
        using System.Windows.Media;
        using System.Windows.Media.Imaging;
        using System.Windows.Shapes;
        using System.Xml;
        using System.Xml.Serialization;
        //using CoreElements.Core.Interlocking;
        using System.Xml.Linq;
        using System.Reflection;

        namespace TreeviewTest.Stck
        {
            /// <summary>
            /// Interaction logic for Window1.xaml
            /// </summary>
            public partial class Window1 : Window
            {
                public Window1()
                {
                    InitializeComponent();
                }


                private void ExecutedLoadXML(object sender, ExecutedRoutedEventArgs e)
                {

                    string executableLocation = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                    string xslLocation = System.IO.Path.Combine(executableLocation, "Interlocking.xml");

                    XDocument xmlData = XDocument.Load(xslLocation, LoadOptions.None);
                    var Interlocking = XmlSerializationHelper.LoadFromXML<Interlocking>(xmlData.ToString());

                    var children = new List<Interlocking>();
                    children.Add(Interlocking);

                    treeView1.ItemsSource = null;
                    treeView1.Items.Clear();
                    treeView1.ItemsSource = children;
                }

                private void ExecutedSaveXML(object sender, ExecutedRoutedEventArgs e)
                {
                    var planList = treeView1.ItemsSource as IList<Interlocking>;
                    if (planList != null && planList.Count > 0)
                    {
                        // Kludge to force pending edits to update
                        treeView1.Focus();
                        // Replace with actual save code!
                        Debug.WriteLine(planList[0].GetXml());
                    }
                }
            }

            public static class CustomCommands
            {
                public static readonly RoutedUICommand LoadXMLCommand = new RoutedUICommand("Load XML", "LoadXML", typeof(Window1));

                public static readonly RoutedUICommand SaveXMLCommand = new RoutedUICommand("Save XML", "SaveXML", typeof(Window1));
            }

            public static class XmlSerializationHelper
            {
                public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
                {
                    using (var textWriter = new StringWriter())
                    {
                        XmlWriterSettings settings = new XmlWriterSettings();
                        settings.Indent = true;        // For cosmetic purposes.
                        settings.IndentChars = "    "; // For cosmetic purposes.
                        using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                        {
                            if (omitStandardNamespaces)
                            {
                                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                                ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
                                serializer.Serialize(xmlWriter, obj, ns);
                            }
                            else
                            {
                                serializer.Serialize(xmlWriter, obj);
                            }
                        }
                        return textWriter.ToString();
                    }
                }

                public static string GetXml<T>(this T obj, bool omitNamespace)
                {
                    XmlSerializer serializer = new XmlSerializer(obj.GetType());
                    return GetXml(obj, serializer, omitNamespace);
                }

                public static string GetXml<T>(this T obj)
                {
                    return GetXml(obj, false);
                }

                public static T LoadFromXML<T>(this string xmlString)
                {
                    return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
                }

                public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
                {
                    T returnValue = default(T);

                    using (StringReader reader = new StringReader(xmlString))
                    {
                        object result = serial.Deserialize(reader);
                        if (result is T)
                        {
                            returnValue = (T)result;
                        }
                    }
                    return returnValue;
                }

                public static T LoadFromFile<T>(string filename)
                {
                    XmlSerializer serial = new XmlSerializer(typeof(T));
                    try
                    {
                        using (var fs = new FileStream(filename, FileMode.Open))
                        {
                            object result = serial.Deserialize(fs);
                            if (result is T)
                            {
                                return (T)result;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        throw;
                    }
                    return default(T);
                }
            }
        }

XAML:

        <Window x:Class="Test_Thesis.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                xmlns:o="clr-namespace:Test_Thesis"
                mc:Ignorable="d"
              Title="Window1" Height="300" Width="600">
            <Window.CommandBindings>
                <CommandBinding Command="o:CustomCommands.LoadXMLCommand"  Executed="ExecutedLoadXML"/>
                <CommandBinding Command="o:CustomCommands.SaveXMLCommand" Executed="ExecutedSaveXML"/>
            </Window.CommandBindings>
            <Window.Resources>
                <HierarchicalDataTemplate  DataType="{x:Type o:Interlocking}" ItemsSource="{Binding Path=Signals}">
                    <TextBlock Text="Interlocking">
                    </TextBlock>
                </HierarchicalDataTemplate >
                <HierarchicalDataTemplate  DataType="{x:Type o:Signals}" ItemsSource="{Binding Path=Signal}">
                    <TextBlock Text="Signal">
                    </TextBlock>
                </HierarchicalDataTemplate >

                <!--<HierarchicalDataTemplate  DataType="{x:Type o:Signal}" ItemsSource="{Binding Path=AspectSpeedDependencies}">
                    <TextBlock Text="Signals">
                    </TextBlock>
                </HierarchicalDataTemplate >
                <HierarchicalDataTemplate  DataType="{x:Type o:AspectSpeedDependencies}" ItemsSource="{Binding Path=AspectSpeedDependency}">
                    <TextBlock Text="AspectSpeedDependencies">
                    </TextBlock>
                </HierarchicalDataTemplate >-->

                <HierarchicalDataTemplate  DataType="{x:Type o:Signal}" ItemsSource="{Binding Path=AspectSpeedDependencies}">
                    <Grid Margin="3" MinWidth="300">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="Ref" Grid.Column="0" Grid.Row="0"/>
                        <TextBox Text="{Binding Path=Ref, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/>
                    </Grid>
                </HierarchicalDataTemplate >
                <HierarchicalDataTemplate  DataType="{x:Type o:AspectSpeedDependencies}" ItemsSource="{Binding Path=AspectSpeedDependency}">
                    <TextBlock Text="AspectSpeedDependencies">
                    </TextBlock>
                </HierarchicalDataTemplate >

                <HierarchicalDataTemplate  DataType="{x:Type o:AspectSpeedDependency}" ItemsSource="{Binding Path=TargetRef}">

                    <Border BorderBrush="Gray" BorderThickness="1" MinWidth="300">
                        <StackPanel Height="auto" Width="auto">
                            <TextBlock Text="AspectSpeedDependency:" />

                                <StackPanel Orientation="Horizontal">

                                    <TextBlock Text="Aspect:" Margin="1"/>
                                <TextBox Text="{Binding Path=Aspect, Mode=TwoWay}" Margin="1"/>
                                <TextBlock Text="VApproach:" Margin="1"/>
                                <TextBox Text="{Binding Path=VApproach, Mode=TwoWay}" Margin="1"/>
                                <TextBlock Text="VPass:" Margin="1"/>
                                <TextBox Text="{Binding Path=VPass, Mode=TwoWay}" Margin="1"/>
                            </StackPanel>



                                <!--<TextBlock Text="Aspect:" Grid.Column="0" Grid.Row="2"/>
                                <TextBox Text="{Binding Path=Aspect, Mode=TwoWay}" Grid.Column="1" Grid.Row="2"/>
                                <TextBlock Text="VApproach:" Grid.Column="0" Grid.Row="3"/>
                                <TextBox Text="{Binding Path=VApproach, Mode=TwoWay}" Grid.Column="1" Grid.Row="3"/>
                                <TextBlock Text="VPass:" Grid.Column="0" Grid.Row="4"/>
                                <TextBox Text="{Binding Path=VPass, Mode=TwoWay}" Grid.Column="1" Grid.Row="4"/>-->



                        </StackPanel>

                    </Border>
                </HierarchicalDataTemplate >

                <DataTemplate  DataType="{x:Type o:TargetRef}">
                    <Border BorderBrush="Brown" BorderThickness="1" MinWidth="300">
                        <Grid Margin="3" >
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="Ref:" Grid.Column="0" Grid.Row="0"/>
                            <TextBox Text="{Binding Path=Ref, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/>



                        </Grid>
                    </Border>
                </DataTemplate >
    <!-- if we remove below element it will show first leg of xml structure-->
                <HierarchicalDataTemplate  DataType="{x:Type o:Interlocking}" ItemsSource="{Binding Path=Routes}">
                    <TextBlock Text="Routes">
                    </TextBlock>
                </HierarchicalDataTemplate > 
       </Window.Resources>
            <DockPanel>
                <ToolBarTray DockPanel.Dock="Top">
                    <ToolBar>
                        <Button Command="o:CustomCommands.LoadXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/>
                        <Button Command="o:CustomCommands.SaveXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/>
                    </ToolBar>
                </ToolBarTray>
                <Grid DockPanel.Dock="Bottom">
                    <TreeView Margin="3" Name="treeView1">
                        <TreeView.ItemContainerStyle>
                            <Style TargetType="{x:Type TreeViewItem}">
                                <Setter Property="IsExpanded" Value="True" />
                            </Style>
                        </TreeView.ItemContainerStyle>
                    </TreeView>
                </Grid>
            </DockPanel>
        </Window>

XML C#代码

   using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;


    namespace TreeviewTest.Stck
    {



    [XmlRoot(ElementName = "targetRef")]
    public class TargetRef
    {
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
    }

    [XmlRoot(ElementName = "aspectSpeedDependency")]
    public class AspectSpeedDependency
    {
        [XmlElement(ElementName = "targetRef")]
        public List<TargetRef> TargetRef { get; set; }
        [XmlAttribute(AttributeName = "aspect")]
        public string Aspect { get; set; }
        [XmlAttribute(AttributeName = "vApproach")]
        public string VApproach { get; set; }
        [XmlAttribute(AttributeName = "vPass")]
        public string VPass { get; set; }
    }

    [XmlRoot(ElementName = "aspectSpeedDependencies")]
    public class AspectSpeedDependencies
    {
        [XmlElement(ElementName = "aspectSpeedDependency")]
        public List<AspectSpeedDependency> AspectSpeedDependency { get; set; }
    }

    [XmlRoot(ElementName = "signal")]
    public class Signal
    {
        [XmlElement(ElementName = "aspectSpeedDependencies")]
        public List<AspectSpeedDependencies> AspectSpeedDependencies { get; set; }
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
    }

    [XmlRoot(ElementName = "signals")]
    public class Signals
    {
        [XmlElement(ElementName = "signal")]
        public List<Signal> Signal { get; set; }
    }

    [XmlRoot(ElementName = "signalRef")]
    public class SignalRef
    {
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
    }

    [XmlRoot(ElementName = "start")]
    public class Start
    {
        [XmlElement(ElementName = "signalRef")]
        public List<SignalRef> SignalRef { get; set; }
    }

    [XmlRoot(ElementName = "target")]
    public class Target
    {
        [XmlElement(ElementName = "signalRef")]
        public List<SignalRef> SignalRef { get; set; }
    }

    [XmlRoot(ElementName = "switch")]
    public class Switch
    {
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
        [XmlAttribute(AttributeName = "course")]
        public string Course { get; set; }
    }

    [XmlRoot(ElementName = "switchRef")]
    public class SwitchRef
    {
        [XmlElement(ElementName = "switch")]
        public List<Switch> Switch { get; set; }
    }

    [XmlRoot(ElementName = "levelcrossing")]
    public class Levelcrossing
    {
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
        [XmlAttribute(AttributeName = "beam")]
        public string Beam { get; set; }
    }

    [XmlRoot(ElementName = "levelcrossingRef")]
    public class LevelcrossingRef
    {
        [XmlElement(ElementName = "levelcrossing")]
        public List<Levelcrossing> Levelcrossing { get; set; }
    }

    [XmlRoot(ElementName = "trackCircuitBorder")]
    public class TrackCircuitBorder
    {
        [XmlAttribute(AttributeName = "ref")]
        public string Ref { get; set; }
    }

    [XmlRoot(ElementName = "trainDetectorRef")]
    public class TrainDetectorRef
    {
        [XmlElement(ElementName = "trackCircuitBorder")]
        public List<TrackCircuitBorder> TrackCircuitBorder { get; set; }
    }

    [XmlRoot(ElementName = "elements")]
    public class Elements
    {
        [XmlElement(ElementName = "switchRef")]
        public List<SwitchRef> SwitchRef { get; set; }
        [XmlElement(ElementName = "levelcrossingRef")]
        public List<LevelcrossingRef> LevelcrossingRef { get; set; }
        [XmlElement(ElementName = "trainDetectorRef")]
        public List<TrainDetectorRef> TrainDetectorRef { get; set; }

        [XmlIgnore]
        public IList ElementChildren
        {
            get
            {
                return new CompositeCollection()
            {
                new CollectionContainer() { Collection = SwitchRef },
                new CollectionContainer() { Collection = LevelcrossingRef },
                new CollectionContainer() { Collection = TrainDetectorRef }
            };
            }
        }
    }

    [XmlRoot(ElementName = "routePriority")]
    public class RoutePriority
    {
        [XmlAttribute(AttributeName = "rank")]
        public string Rank { get; set; }
    }

    [XmlRoot(ElementName = "route")]
    public class Route
    {
        [XmlElement(ElementName = "start")]
        public List<Start> Start { get; set; }
        [XmlElement(ElementName = "target")]
        public List<Target> Target { get; set; }
        [XmlElement(ElementName = "elements")]
        public List<Elements> Elements { get; set; }
        [XmlElement(ElementName = "flankElements")]
        public string FlankElements { get; set; }
        [XmlElement(ElementName = "routePriority")]
        public List<RoutePriority> RoutePriority { get; set; }
        [XmlAttribute(AttributeName = "id")]
        public string Id { get; set; }

        [XmlIgnore]
        public IList RouteChildern
        {
            get
            {
                return new CompositeCollection()
            {
                new CollectionContainer() { Collection = Start },
                new CollectionContainer() { Collection = Target },
                new CollectionContainer() { Collection = Elements },

                new CollectionContainer() { Collection = RoutePriority }

            };
            }
        }
    }


    [XmlRoot(ElementName = "routes")]
    public class Routes
    {
        [XmlElement(ElementName = "route")]
        public List<Route> Route { get; set; }
    }

    [XmlRoot(ElementName = "interlocking")]
    public class Interlocking
    {
        [XmlElement(ElementName = "signals")]
        public List<Signals> Signals { get; set; }
        [XmlElement(ElementName = "routes")]
        public List<Routes> Routes { get; set; }
        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsi { get; set; }
        [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsd { get; set; }

        [XmlIgnore]
        public IList InterlockingChildren
        {
            get
            {
                return new CompositeCollection()
            {
                new CollectionContainer() { Collection = Signals },
                new CollectionContainer() { Collection = Routes }
            };
            }
        }
    }
}

/// UPDATE ///

    private void ExecutedSaveXML(object sender, ExecutedRoutedEventArgs e)
    {
        var planList = treeView1.ItemsSource as IList<Interlocking>;
        if (planList != null && planList.Count > 0)
        {

            treeView1.Focus();

            // Replace Debug.WriteLine(planList[0].GetXml()); with following

            Debug.WriteLine(planList[0].GetXml(true));

        }
    }
}

如果我们在此函数中发送“true”,则在辅助类中已经考虑了名称空间问题。但是@ J.H解决方案要好得多。减少字符串操作总是很好。

1 个答案:

答案 0 :(得分:2)

如果在类Interlocking中注释掉Xsi / Xsd属性并向Children添加XmlIgnore属性,则它可以正常工作。 xsi / xsd命名空间甚至在输出中。

[XmlRoot(ElementName = "interlocking")]
public class Interlocking
{
    [XmlElement(ElementName = "signals")]
    public List<Signals> Signals { get; set; }
    [XmlElement(ElementName = "routes")]
    public List<Routes> Routes { get; set; }

    //[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
    //public string Xsi { get; set; }
    //[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
    //public string Xsd { get; set; }

    [XmlIgnore]
    public IList Children
    {
        get
        {
            return new CompositeCollection()
            {
                new CollectionContainer() { Collection = Signals },
                new CollectionContainer() { Collection = Routes }
            };
        }
    }
}

输出:

<interlocking xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <signals>
        <signal ref="SignalRef_1">
            <aspectSpeedDependencies>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
            </aspectSpeedDependencies>
        </signal>
        <signal ref="SignalRef_1">
            <aspectSpeedDependencies>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
                <aspectSpeedDependency aspect="REF" vApproach="VApproach" vPass="Vpas">
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                    <targetRef ref="TargetRef" />
                </aspectSpeedDependency>
            </aspectSpeedDependencies>
        </signal>
    </signals>
    <routes>
        <route id="1">
            <start>
                <signalRef ref="pro.Routes.Route.Start.SignalRef.Ref" />
            </start>
            <target>
                <signalRef ref="Target.SingalRef" />
            </target>
            <elements>
                <switchRef>
                    <switch ref="Ref" course="Left" />
                </switchRef>
                <levelcrossingRef>
                    <levelcrossing ref="Ref" beam="Beam" />
                    <levelcrossing ref="Ref" beam="Beam" />
                    <levelcrossing ref="Ref" beam="Beam" />
                </levelcrossingRef>
                <trainDetectorRef>
                    <trackCircuitBorder ref="Ref" />
                    <trackCircuitBorder ref="Ref" />
                    <trackCircuitBorder ref="Ref" />
                </trainDetectorRef>
            </elements>
            <flankElements>Flank</flankElements>
            <routePriority rank="1" />
        </route>
    </routes>
</interlocking>