XML将对象序列化为不同的输出格式

时间:2015-01-21 23:50:28

标签: xml vb.net xslt xml-serialization

我使用XmlSerializerXmlType / XmlAttribute属性将XML序列化和反序列化为容器对象。

输入XML:

 <row identifier="blah" firstname="blah" lastname="blah" />

对象:

<Serializable(), XmlType("row")> _
Public Class RowEmployee
    <XmlAttribute("identifier")> _
    Public EmployeeIdentifier As String

    <XmlAttribute("firstname")> _
    Public FirstName As String

    <XmlAttribute("middlename")> _
    Public MiddleName As String

    <XmlAttribute("lastname")> _
    Public LastName As String

End Class

这种方法很好,干净/简单,与输入XML格式匹配,并且可以很好地转换为XML,唯一的问题是我的输出XML格式略有不同,例如。

 <employee Identifier="blah" FirstName="blah" .....>

我没有太多使用XSLT的经验,但我有点假设这是一种方法。在这种设置下,还有其他方法比XSLT更简单吗?

此外,如果有人知道有任何好的资源用于&#34;速成课程&#34;在类似的上下文中使用XSLT与.NET,非常感谢。

2 个答案:

答案 0 :(得分:0)

您是否希望将每个RowEmployee类序列化为xml中的“row”元素?您需要将此指定为使用此类的ElementName,例如:

[XmlElement("row")]
public rows As List(Of RowEmployee)

答案 1 :(得分:0)

Re:@ afrogonabike的回答,是的,我确实有一个容器类,我为了对对象的反序列化而掩盖:

<Serializable(), XmlRoot("data"), XmlType("data")> _
Public Class AesopEmployeeCollection
    <XmlElement("row")> _
    Public Employees As List(Of AesopEmployee)

    Public Sub New()
        Me.Employees = New List(Of AesopEmployee)()
    End Sub

    Public Function GetEmployeeInfo(AesopId As String) As AesopEmployee
        Return (From e In Employees Where e.EmployeeIdentifier = AesopId).FirstOrDefault()
    End Function
End Class

我最终使用XSLT,转换实际上非常简单:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="row">
    <employees>
        <employee>
            <xsl:attribute name="Identifier">
                <xsl:value-of select="@identifier" />
            </xsl:attribute>
            <xsl:attribute name="FirstName">
                <xsl:value-of select="@firstname" />
            </xsl:attribute>
            <!-- dont send middlename if blank -->
            <xsl:if test="string-length(@middlename)!=0">
               <xsl:attribute name="MiddleName">
                   <xsl:value-of select="@middlename" />
               </xsl:attribute>
            </xsl:if>  
            <xsl:attribute name="LastName">
                 <xsl:value-of select="@lastname" />
            </xsl:attribute>
            ......
        </employee>
    </employees>
</xsl:template>

</xsl:stylesheet>   

序列化/转换逻辑也不错:

        Dim Ms As New System.IO.MemoryStream()
        Dim Xslt As New XslCompiledTransform()
        Xslt.Load(System.Web.HttpContext.Current.Server.MapPath("/MyRoot/Xslt/EmployeeInfo.xslt"))

        Using Xtw As New System.Xml.XmlTextWriter(Ms, System.Text.Encoding.UTF8)
            SharedInfo.EmpSerializer.Serialize(Xtw, RowEmp)
            Ms = DirectCast(Xtw.BaseStream, System.IO.MemoryStream)
            Ms.Seek(0, SeekOrigin.Begin)
            Dim XmlReader As New XmlTextReader(Ms)
            Dim sb As New StringBuilder()
            Dim WriterSettings As New XmlWriterSettings()
            WriterSettings.OmitXmlDeclaration = True
            Using XmlWriter As XmlWriter = XmlWriter.Create(sb, WriterSettings)
                Xslt.Transform(XmlReader, XmlWriter)
                Dim XmlResponse = EmpImportService.AddOrUpdate(sb.ToString(), ServiceApiKey)

                For Each ResponseNode As XmlNode In XmlResponse.ChildNodes
                    ResponseMessage.Append("<li>").Append(ResponseNode.Attributes("message").Value).Append("</li>")
                Next
            End Using
        End Using