2015-08-27 5 views
1

Возможно, я собираюсь сделать это неправильно, но пока я не столкнулся с этой проблемой, это казалось довольно элегантным способом реализации моего требования, у меня есть загрузка кода на основе xpath, который изменяет документ. Он довольно старый, и я обновляю его сейчас, чтобы сделать его более управляемым, добавляя некоторые дополнительные функции.XDocument Load on Inherited Class - Невозможно использовать

Я думал, что было бы целесообразно создать класс 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 

Я просто хочу, чтобы иметь возможность загрузить DOC-то вроде:

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

ответ

1

Лучший способ: Вы не перезаписать XDocument. Вы скорее создадите обертку вокруг XDocument, которая хранит ссылку на загруженный документ и позволяет вам получить доступ к ней так, как вы хотите. I высоко рекомендую сделать это вот так.

Ваш класс может выглядеть следующим образом:

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 метод загрузки, чтобы заставить использовать ваш метод, и вы должны использовать Copy-Constructor из XDocument, чтобы получить ваш документ правильно. Таким образом, это может выглядеть так:

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 тем, кто когда-либо использовал ваш класс.

К вашему первоначальному вопросу, почему отличное от XDocument до DocXDocument2 не удалось. Причина в том, что функция XDocument.Load создает XDocument, а не DocXDocument2. Вы можете легко отнести экземпляр определенного класса к любому классу или интерфейсу, который реализуется объектом. Но вы не можете передать его объекту, который сужает реализацию конкретного объекта. Вы должны создать экземпляр как DocXDocument2, чтобы получить экземпляр этого типа.

+0

Благодарим вас, ответ на лучший класс. Думаю, в этом случае я воспользуюсь вашим вторым примером, поскольку я уже поставил больше кода для этого метода, и я как бы наслаждаюсь использованием возможностей xml vb.net, таких как Me ... ! :-) –

+1

Вы были предупреждены ;-) Но именно по этой причине я представил оба примера. Не забывайте отмечать ответ. – Nitram

+0

Уже отмечен как ответ, из интереса в первом примере, если я хотел отредактировать xml, я просто должен был бы использовать _doc.descendants и т. Д. Вместо Me.descendants? –