继承类上的XDocument加载 - 无法转换

时间:2015-08-27 13:31:09

标签: .net xml vb.net

也许我会以错误的方式解决这个问题,但在我遇到这个问题之前,它似乎是一种相当优雅的方式来实现我的要求,我有一堆基于xpath的代码来修改word文档。它已经很老了,我现在正在升级它,以便在添加一些额外功能时更易于管理。

我想,创建一个DocxDocument类并让它继承XDocument类是有意义的,这样我就可以使用System.Xml.Linq和System.Xml.Xpath来编辑底层的xml文档。

我错误地认为,如果XDocument继承了该类型,则可以将其转换为DocXDocument。那么,看下面的代码我怎么加载和XDocument到DocXDocument?

Public Class DocXDocument2
    Inherits XDocument

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overloads Function Load(DocumentPath As String) As XDocument
        Using pkg = WordprocessingDocument.Open(DocumentPath, True)
            Return XDocument.Load(pkg.MainDocumentPart.GetStream())
        End Using
    End Function

End Class

我只是希望能够加载类似以下内容的文档:

dim docx = DocXDocument.load("C:\temp.docx")

1 个答案:

答案 0 :(得分:0)

最好的方法是:不要覆盖XDocument。您宁可在XDocument周围创建一个包装器,它存储对已加载文档的引用,并允许您以您希望的方式访问它。我高度建议这样做。

你的课程看起来像这样:

Public Class DocXDocument2
    Private ReadOnly _doc As XDocument

    Private Sub New(doc As XDocument)
        _doc = doc
    End Sub

    Public Shared Function Load(DocumentPath As String) As XDocument
        Using pkg = WordprocessingDocument.Open(DocumentPath, True)
            Return New DocXDocument2(XDocument.Load(pkg.MainDocumentPart.GetStream()))
        End Using
    End Function

    Public Function Descendants As IEnumerable(Of XElement)
        Return _doc.Descendants 
    End Function
End Class

请注意,原始XDocument会将加载函数公开为Shared函数。所以我在这里改变了。

有多少方法可以通过继承来完成它。但它并不漂亮。您必须使用Shadow加载方法来强制使用您的方法,并且必须使用XDocument的Copy-Constructor来正确地获取文档。所以它看起来像这样:

Public Class DocXDocument2
    Inherits XDocument

    Private Sub New(doc As XDocument)
        MyBase.New(doc)
    End Sub

    Public Shared Shadows Function Load(DocumentPath As String) As XDocument
        Using pkg = WordprocessingDocument.Open(DocumentPath, True)
            Return New DocXDocument2(XDocument.Load(pkg.MainDocumentPart.GetStream()))
        End Using
    End Function
End Class

这只是为了尽可能贴近您的方法。我真的建议使用第一种方法。它是更清晰的代码,它可以让您更好地控制对文档执行的操作以及不执行的操作。继承XDocument之后,public每个XDocument方法都会使用您的班级。{/ p>

对于您的初始问题,为什么XDocumentDocXDocument2的演员表失败了。原因很简单,XDocument.Load函数会创建XDocument而不是DocXDocument2。您可以轻松地将特定类的实例强制转换为该对象实现的任何类或接口。但是您无法将其强制转换为缩小特定对象实现的对象。您必须将实例构造为DocXDocument2以获取此类型的实例。