【问题标题】:Preserve Xml Xsd schemaLocation when deserializing then serializing反序列化然后序列化时保留 Xml Xsd schemaLocation
【发布时间】:2021-11-28 18:50:34
【问题描述】:

我将一个 Xml 文件反序列化为一个 .NET 类,修改属性,然后序列化回同一个文件。这是 .NET 模型 (vb.net)

<XmlRoot("StationSetpoints")>
Public Class XmlStationSetpoints
    <XmlElement("Setpoint")>
    Public Property Setpoints As List(Of XmlStationSetpointsSetpoint)
End Class

<Serializable>
Public Class XmlStationSetpointsSetpoint
    <XmlElement("Point")>
    Public Property Points As List(Of XmlStationSetpointsSetpointPoint)
    ' etc...
End Class

反序列化和序列化(c#)

var settings = New XmlStationSetpoints();
var serializer = New XmlSerializer(XmlStationSetpoints);
// deserialize
using StreamReader sr = new StreamReader(path)
    settings = (XmlStationSetpoints)serializer.Deserialize(sr);
// serialize
using StreamWriter sw = new StreamWriter(path, false)
    serializer.Serialize(sw, settings);

原始 Xml 文件,包括位于 Xml 文件 xsi:schemaLocation="http://www.w3schools.com StationSetpoints.xsd" 旁边的本地架构文件(第 5 行)

<?xml version="1.0" encoding="utf-8"?>
<StationSetpoints
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xsi:schemaLocation="http://www.w3schools.com StationSetpoints.xsd">
  <Setpoint PartNumber="108022">
    <Point InstrumentName="PD Stage" Value="10"/>
  </Setpoint>
  <Setpoint PartNumber="107983">
    <Point Order="2" InstrumentName="PD Stage" Value="7.5"/>
  </Setpoint>
</StationSetpoints>

当文件被序列化时,该架构路径不包括在内

<?xml version="1.0" encoding="utf-8"?>
<StationSetpoints 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Setpoint PartNumber="108022">
    <Point Order="0" InstrumentName="PD Stage" Value="10"></Point>
  </Setpoint>
  <Setpoint PartNumber="107983">
    <Point Order="2" InstrumentName="PD Stage" Value="7.5"></Point>
  </Setpoint>
</StationSetpoints>

如何在 .NET 类中保留该架构路径,以便序列化文件包含它?

【问题讨论】:

    标签: c# xml vb.net xml-serialization


    【解决方案1】:

    您可以通过为此目的添加显式属性来反序列化和重新序列化xsi:schemaLocation 属性,如this answer 中所示dtbXmlSerialization and xsi:SchemaLocation (xsd.exe),适当地翻译成VB .NET:

    Public Partial Class XmlStationSetpoints
        <XmlAttribute("schemaLocation", Namespace:="http://www.w3.org/2001/XMLSchema-instance")>
        Public Property xsiSchemaLocation As String = "http://www.w3schools.com StationSetpoints.xsd"
    End Class
    

    演示小提琴 #1 here.

    如果您想硬编码 xsi:schemaLocation 的值并使其在序列化时无条件显示,您可以使用显式实现的属性来执行此操作,如下所示:

    Public Partial Class XmlStationSetpoints
        <XmlAttribute("schemaLocation", Namespace:="http://www.w3.org/2001/XMLSchema-instance")>
        Public Property xsiSchemaLocation() As String
            Get
                Return "http://www.w3schools.com StationSetpoints.xsd"
            End Get
            Set
                ' Do nothing, it's hardcoded.  A setter is required because XmlSerializer will only serialize properties with public getters and setters.
            End Set
        End Property
    End Class
    

    演示小提琴#2 here.

    如果您想硬编码xsi:schemaLocation 的值,但要控制它是否出现(因为例如它应该只在XmlStationSetpoints 是XML 文件的根元素时出现),您可以使用@ 987654326@ 属性如下:

    Public Partial Class XmlStationSetpoints
        <XmlAttribute("schemaLocation", Namespace:="http://www.w3.org/2001/XMLSchema-instance")>
        Public Property xsiSchemaLocation() As String
            Get
                Return "http://www.w3schools.com StationSetpoints.xsd"
            End Get
            Set
                ' Do nothing, it's hardcoded.  A setter is required because XmlSerializer will only serialize properties with public getters and setters.
            End Set
        End Property
        <XmlIgnore>
        Public Property xsiSchemaLocationSpecified() As Boolean
    End Class
    

    该属性会捕捉反序列化过程中是否遇到xsi:schemaLocation属性,并控制是否在序列化过程中发出该属性。

    演示小提琴#3 here.

    【讨论】:

      猜你喜欢
      • 2016-07-16
      • 1970-01-01
      • 2018-12-11
      • 2018-06-14
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多