'xmlns:xsi' 是重复的属性名称 [英] 'xmlns:xsi' is a duplicate attribute name
问题描述
我正在尝试编写一个 xml 编辑器,可以在其中加载、编辑特定的 xml 文件,然后保存以供进一步使用.所以xml文件的结构不能改变.
我正在尝试关注这个
它说我有一个重复的属性名称,而我正在从文件加载并且没有对该文件进行任何更改.
XML 文件结构:
<?xml version="1.0" encoding="utf-8"?><互锁 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><信号><信号参考="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></信号><信号参考="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></信号></信号><路线><路由id="1"><开始><signalRef ref="pro.Routes.Route.Start.SignalRef.Ref"/></开始><目标><signalRef ref="Target.SingalRef"/></目标><元素><switchRef><switch ref="Ref" course="Left"/></switchRef><levelcrossingRef><levelcrossing ref="Ref" beam="Beam"/><levelcrossing ref="Ref" beam="Beam"/><levelcrossing ref="Ref" beam="Beam"/></levelcrossingRef><trackCircuitBorder ref="Ref"/><trackCircuitBorder ref="Ref"/><trackCircuitBorder ref="Ref"/></trainDetectorRef></元素><flankElements>Flank</flankElements><routePriority rank="1"/></路线></路线></互锁>
背后的代码
使用系统;使用 System.Collections.Generic;使用 System.Diagnostics;使用 System.IO;使用 System.Linq;使用 System.Text;使用 System.Threading.Tasks;使用 System.Windows;使用 System.Windows.Controls;使用 System.Windows.Data;使用 System.Windows.Documents;使用 System.Windows.Input;使用 System.Windows.Media;使用 System.Windows.Media.Imaging;使用 System.Windows.Shapes;使用 System.Xml;使用 System.Xml.Serialization;//使用CoreElements.Core.Interlocking;使用 System.Xml.Linq;使用 System.Reflection;命名空间 TreeviewTest.Stck{///<总结>///Window1.xaml 的交互逻辑///</总结>公共部分类 Window1 : 窗口{公共窗口 1(){初始化组件();}私有无效 ExecutedLoadXML(对象发送者,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(xmlData.ToString());var children = new List();children.Add(互锁);treeView1.ItemsSource = null;treeView1.Items.Clear();treeView1.ItemsSource = 儿童;}私有无效 ExecutedSaveXML(对象发送者,ExecutedRoutedEventArgs e){var planList = treeView1.ItemsSource as IList;if (planList != null && planList.Count > 0){//Kludge 强制挂起的编辑更新treeView1.Focus();//替换为实际的保存代码!Debug.WriteLine(planList[0].GetXml());}}}公共静态类 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));}公共静态类 XmlSerializationHelper{公共静态字符串 GetXml(T obj,XmlSerializer 序列化程序,bool omitStandardNamespaces){使用 (var textWriter = new StringWriter()){XmlWriterSettings settings = new XmlWriterSettings();settings.Indent = true;//用于装饰目的.settings.IndentChars = " ";//用于装饰目的.使用 (var xmlWriter = XmlWriter.Create(textWriter, settings)){如果(省略标准命名空间){XmlSerializerNamespaces ns = new XmlSerializerNamespaces();ns.Add("", "");//禁用 xmlns:xsi 和 xmlns:xsd 行.serializer.Serialize(xmlWriter, obj, ns);}别的{serializer.Serialize(xmlWriter, obj);}}返回 textWriter.ToString();}}public static string GetXml(this T obj, bool omitNamespace){XmlSerializer 序列化器 = new XmlSerializer(obj.GetType());返回 GetXml(obj, serializer, omitNamespace);}public static string GetXml(this T obj){返回 GetXml(obj, false);}public static T LoadFromXML(这个字符串xmlString){返回 xmlString.LoadFromXML(new XmlSerializer(typeof(T)));}public static T LoadFromXML(这个字符串 xmlString,XmlSerializer 序列号){T returnValue = default(T);使用 (StringReader reader = new StringReader(xmlString)){对象结果 = serial.Deserialize(reader);如果(结果是 T){returnValue = (T)result;}}返回返回值;}public static T LoadFromFile(字符串文件名){XmlSerializer serial = new XmlSerializer(typeof(T));尝试{使用 (var fs = new FileStream(filename, FileMode.Open)){对象结果 = serial.Deserialize(fs);如果(结果是 T){返回 (T) 结果;}}}捕获(异常前){Debug.WriteLine(ex.ToString());扔;}返回默认值(T);}}}
XAML:
<Window.CommandBindings><CommandBinding Command="o:CustomCommands.LoadXMLCommand" Executed="ExecutedLoadXML"/><CommandBinding Command="o:CustomCommands.SaveXMLCommand" Executed="ExecutedSaveXML"/></Window.CommandBindings><窗口.资源><HierarchicalDataTemplate DataType="{x:Type o:Interlocking}" ItemsSource="{Binding Path=Signals}"><TextBlock Text="互锁"></TextBlock></HierarchicalDataTemplate ><HierarchicalDataTemplate DataType="{x:Type o:Signals}" ItemsSource="{Binding Path=Signal}"><TextBlock Text="信号"></TextBlock></HierarchicalDataTemplate ><!--<HierarchicalDataTemplate DataType="{x:Type o:Signal}" ItemsSource="{Binding Path=AspectSpeedDependencies}"><TextBlock Text="信号"></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><行定义/></Grid.RowDefinitions><Grid.ColumnDefinitions><列定义/><列定义/></Grid.ColumnDefinitions><TextBlock Text="Ref" Grid.Column="0" Grid.Row="0"/><TextBox Text="{Binding Path=Ref, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/></网格></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="水平"><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></边框></HierarchicalDataTemplate ><DataTemplate DataType="{x:Type o:TargetRef}"><Border BorderBrush="Brown" BorderThickness="1" MinWidth="300"><Grid Margin="3" ><Grid.RowDefinitions><行定义/><行定义/><行定义/><行定义/></Grid.RowDefinitions><Grid.ColumnDefinitions><列定义/><列定义/></Grid.ColumnDefinitions><TextBlock Text="Ref:" Grid.Column="0" Grid.Row="0"/><TextBox Text="{Binding Path=Ref, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/></网格></边框></数据模板 ><!-- 如果我们删除下面的元素,它将显示 xml 结构的第一条腿--><HierarchicalDataTemplate DataType="{x:Type o:Interlocking}" ItemsSource="{Binding Path=Routes}"><TextBlock Text="路由"></TextBlock></HierarchicalDataTemplate ></Window.Resources><DockPanel><ToolBarTray DockPanel.Dock="Top"><工具栏><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}"/></工具栏></ToolBarTray><Grid DockPanel.Dock="底部"><TreeView Margin="3" Name="treeView1"><TreeView.ItemContainerStyle><Style TargetType="{x:Type TreeViewItem}"><Setter Property="IsExpanded" Value="True"/></风格></TreeView.ItemContainerStyle></树视图></网格></DockPanel></窗口>
XML C# 代码
使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Text;使用 System.Threading.Tasks;使用 System.Xml.Serialization;命名空间 TreeviewTest.Stck{[XmlRoot(ElementName = "targetRef")]公共类 TargetRef{[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}}[XmlRoot(ElementName = "aspectSpeedDependency")]公共类 AspectSpeedDependency{[XmlElement(ElementName = "targetRef")]公共列表目标引用 { 获取;放;}[XmlAttribute(AttributeName = "aspect")]公共字符串方面{获取;放;}[XmlAttribute(AttributeName = "vApproach")]公共字符串 VApproach { 获取;放;}[XmlAttribute(AttributeName = "vPass")]公共字符串 VPass { 获取;放;}}[XmlRoot(ElementName = "aspectSpeedDependencies")]公共类 AspectSpeedDependencies{[XmlElement(ElementName = "aspectSpeedDependency")]公共列表AspectSpeedDependency { 获取;放;}}[XmlRoot(ElementName = "signal")]公共课信号{[XmlElement(ElementName = "aspectSpeedDependencies")]公共列表<AspectSpeedDependencies>AspectSpeedDependencies { 获取;放;}[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}}[XmlRoot(ElementName = "signals")]公共类信号{[XmlElement(ElementName = "signal")]公共列表<信号>信号{得到;放;}}[XmlRoot(ElementName = "signalRef")]公共类 SignalRef{[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}}[XmlRoot(ElementName = "start")]公开课开始{[XmlElement(ElementName = "signalRef")]公共列表信号引用 { 获取;放;}}[XmlRoot(ElementName = "target")]公开课目标{[XmlElement(ElementName = "signalRef")]公共列表信号引用 { 获取;放;}}[XmlRoot(ElementName = "switch")]公共类开关{[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}[XmlAttribute(AttributeName = "课程")]公共字符串课程{获取;放;}}[XmlRoot(ElementName = "switchRef")]公共类 SwitchRef{[XmlElement(ElementName = "switch")]公共列表<开关>开关{得到;放;}}[XmlRoot(ElementName = "levelcrossing")]公共课Levelcrossing{[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}[XmlAttribute(AttributeName = "beam")]公共字符串梁{获取;放;}}[XmlRoot(ElementName = "levelcrossingRef")]公共类 LevelcrossingRef{[XmlElement(ElementName = "levelcrossing")]公共列表平交{得到;放;}}[XmlRoot(ElementName = "trackCircuitBorder")]公共类 TrackCircuitBorder{[XmlAttribute(AttributeName = "ref")]公共字符串 Ref { 获取;放;}}[XmlRoot(ElementName = "trainDetectorRef")]公共类 TrainDetectorRef{[XmlElement(ElementName = "trackCircuitBorder")]公共列表TrackCircuitBorder { 获取;放;}}[XmlRoot(ElementName = "元素")]公共类元素{[XmlElement(ElementName = "switchRef")]公共列表SwitchRef { 获取;放;}[XmlElement(ElementName = "levelcrossingRef")]公共列表LevelcrossingRef { 得到;放;}[XmlElement(ElementName = "trainDetectorRef")]公共列表TrainDetectorRef { 获取;放;}[XmlIgnore]公共 IList ElementChildren{得到{返回新的复合集合(){new CollectionContainer() { Collection = SwitchRef },new CollectionContainer() { Collection = LevelcrossingRef },new CollectionContainer() { Collection = TrainDetectorRef }};}}}[XmlRoot(ElementName = "routePriority")]公共类 RoutePriority{[XmlAttribute(AttributeName = "rank")]公共字符串排名{获取;放;}}[XmlRoot(ElementName = "route")]公开课路线{[XmlElement(ElementName = "start")]公共列表<开始>开始{得到;放;}[XmlElement(ElementName = "target")]公共列表<目标>目标{得到;放;}[XmlElement(ElementName = "元素")]公共列表<元素>元素{得到;放;}[XmlElement(ElementName = "flankElements")]公共字符串 FlankElements { 获取;放;}[XmlElement(ElementName = "routePriority")]公共列表RoutePriority { 获取;放;}[XmlAttribute(AttributeName = "id")]公共字符串 ID { 获取;放;}[XmlIgnore]公共 IList RouteChildern{得到{返回新的复合集合(){new CollectionContainer() { Collection = Start },new CollectionContainer() { Collection = Target },new CollectionContainer() { Collection = Elements },新的 CollectionContainer() { Collection = RoutePriority }};}}}[XmlRoot(ElementName = "routes")]公开课路线{[XmlElement(ElementName = "route")]公共列表<路由>路线{得到;放;}}[XmlRoot(ElementName = "interlocking")]公开课互锁{[XmlElement(ElementName = "信号")]公共列表<信号>信号 { 得到;放;}[XmlElement(ElementName = "routes")]公共列表<路线>路线{得到;放;}[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]公共字符串 Xsi { 获取;放;}[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]公共字符串 Xsd { 获取;放;}[XmlIgnore]公共 IList InterlockingChildren{得到{返回新的复合集合(){new CollectionContainer() { Collection = Signals },new CollectionContainer() { Collection = Routes }};}}}}
///更新///
private void ExecutedSaveXML(object sender, ExecutedRoutedEventArgs e){var planList = treeView1.ItemsSource as IList;if (planList != null && planList.Count > 0){treeView1.Focus();//替换 Debug.WriteLine(planList[0].GetXml());与以下Debug.WriteLine(planList[0].GetXml(true));}}}
如果我们在这个函数中发送一个true",命名空间问题已经在助手类中得到处理.但是@J.H 解决方案更好用.较少的字符串操作总是好的.
如果您在 Interlocking 类中注释掉 Xsi/Xsd 属性并向 Children 添加 XmlIgnore 属性,则它可以工作.xsi/xsd 命名空间甚至在输出中.
[XmlRoot(ElementName = "interlocking")]公开课互锁{[XmlElement(ElementName = "信号")]公共列表<信号>信号 { 得到;放;}[XmlElement(ElementName = "routes")]公共列表<路线>路线{得到;放;}//[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]//公共字符串Xsi { get;放;}//[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]//公共字符串Xsd { get;放;}[XmlIgnore]公共 IList 儿童{得到{返回新的复合集合(){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"><信号><信号参考="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></信号><信号参考="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></信号></信号><路线><路由id="1"><开始><signalRef ref="pro.Routes.Route.Start.SignalRef.Ref"/></开始><目标><signalRef ref="Target.SingalRef"/></目标><元素><switchRef><switch ref="Ref" course="Left"/></switchRef><levelcrossingRef><levelcrossing ref="Ref" beam="Beam"/><levelcrossing ref="Ref" beam="Beam"/><levelcrossing ref="Ref" beam="Beam"/></levelcrossingRef><trackCircuitBorder ref="Ref"/><trackCircuitBorder ref="Ref"/><trackCircuitBorder ref="Ref"/></trainDetectorRef></元素><flankElements>Flank</flankElements><routePriority rank="1"/></路线></路线></互锁>
I am trying to write a xml editor where a specific xml file could be loaded , edited and then later-on saved for further usage. so structure of xml file must not changed.
I am trying to follow this Stackoverflow question , but Save XML command is giving exception while writing back to the file. I am getting this error
which says i am having a duplicate attribute name, while i am loading from the file and changed nothing to that file.
XML File Structure:
<?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>
Code Behind
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# code
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));
}
}
}
if we send a "true" in this function, namespace issue is taken cared already in helper class. But @J.H solution is much better to use. Less string manipulation is always good.
If you comment out the Xsi/Xsd properties in class Interlocking and add an XmlIgnore attribute to Children, it works. The xsi/xsd namespace is even in the output.
[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 }
};
}
}
}
Output:
<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>
这篇关于'xmlns:xsi' 是重复的属性名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!