以前紹介しましたが、MicrosoftのVisual Basicの開発チームのブログに、VBでXMLを処理する一連のトピックが載っています.ファイルをコピーする、XSLTと同じような変換処理を記述するというサンプルもあり、なかなかおもしろく読めます.
もう2008年にかかれたものですけれど、これを見て「.NETプラットフォームでXSLTは終焉を迎える?」なんて大仰なことを書いたInfoQの記事もありました.(⇒もちろん2013年の今もXSLTはVBに取って代わられる事態にはなっていませんが...)
さてこの6番目の記事にXMLをコピーする例があります.
[私の以前のコード]⇒ http://blogs.yahoo.co.jp/tnakita/14656952.html
Function ProcessNode(node As XNode) As XNode
Select Case node.NodeType
Case XmlNodeType.Element
Dim elem As XElement = DirectCast(node, XElement)
Dim newElem As XElement = New XElement(elem.Name)
newElem.Add(elem.Attributes)
Dim childNode As IEnumerable(Of XNode) = elem.Nodes
For Each node In childNode
Dim newNode As XNode = ProcessNode(node)
newElem.Add(newNode)
Next
Return newElem
Case XmlNodeType.Text
Dim text As XText = DirectCast(node, XText)
Dim newText As XText = New XText(text.Value)
Return newText
Case XmlNodeType.Whitespace
Dim text As XText = DirectCast(node, XText)
Dim newText As XText = New XText(text.Value)
Return newText
Case Else
Return Nothing
End Select
End Function
問題は要素の処理です.VBチームのブログを参考に書き直すと以下のようになります.
Function ProcessNode(node As XNode) As XNode
Select Case node.NodeType
Case XmlNodeType.Element
Dim elem As XElement = DirectCast(node, XElement)
Return <<%= elem.Name %>
<%= From attribute In elem.Attributes() _
Select attribute %>>
<%= From childNode In elem.Nodes() _
Select ProcessNode(childNode) %>
</>
Case XmlNodeType.Text
Dim text As XText = DirectCast(node, XText)
Dim newText As XText = New XText(text.Value)
Return newText
Case XmlNodeType.Whitespace
Dim text As XText = DirectCast(node, XText)
Dim newText As XText = New XText(text.Value)
Return newText
Case Else
Return Nothing
End Select
End Function
<%= elem.Name %>
と書いて要素名を取得して埋め込めて、
<%= From childNode In elem.Nodes() _
Select ProcessNode(childNode) %>
次は、このブログのなかで紹介されているXSLTを模したコードについて書きたいと思います.