52919
VBによるnodeのグルーピングがしたいのですが、初心者故行き詰っています．ご教示をお願いいたします．

［入力ファイル］  
次のような変則的なHTMLです．bodyの下位は要素で構成されているのではなく`<BR>¶`（¶は改行コード）を単位に区切られています．

```

    <HTML>
    <HEAD>
    <TITLE></TITLE>
    </HEAD>
    <BODY>
    <U>【書類名】　　　　　　　手続補正書</U><BR>
    <SUP>【提出日】</SUP>　　　　　　　平成２０年１月２１日<BR>
    <SUB>【あて先】</SUB>　　　　　　　特許庁長官　殿<BR>
    <FONT SIZE="6">【事件の表示】</FONT><BR>
    <FONT SIZE="5">　　【<U>出願番号</U>】　　　　<?pi 処理命令 ?><!--コメント-->特願<SUP>２０１７</SUP>－<SUB>５０６７２０</SUB></FONT><BR>
    【補正をする者】<BR>
    ...
    </BODY>
    </HTML>
    
```

この`body`タグの下位ノードを、終末の改行でグルーピングしたいのです．

［作成したプログラム］

今できているコードは以下で、このあと`body`配下の`nodes`をどうグルーピングしたらよいかわからなくなっています．

```

        Dim streamReader As StreamReader = New StreamReader("D:\My_Documents\XML2019\JPO-HTML\testdata\F58737H1-mod.html", Encoding.GetEncoding("Shift_JIS"))
        Dim SgmlReader As Sgml.SgmlReader = New Sgml.SgmlReader()
        SgmlReader.DocType = "HTML"
        SgmlReader.WhitespaceHandling = Xml.WhitespaceHandling.All
        SgmlReader.CaseFolding = Sgml.CaseFolding.ToUpper
        SgmlReader.InputStream = streamReader
        Dim doc As XDocument = XDocument.Load(SgmlReader)
        Dim body As XElement = doc.Element("HTML").Element("BODY")
        Dim nodes As IEnumerable(Of XNode) = body.Nodes
    
```

このようなグルーピングは「自分の前の改行の個数を取得する関数」を作って、それをLINQ +
XMLのGroupByに組み込むので良いと思うのですが、その肝心な点がわかりません．

以上 よろしくお願いいたします
CC BY-SA 4.0
2019-02-19T05:50:17.717
52871
2019-02-21T10:23:58.820
2019-02-19T06:13:50.870
19110
9503
question
html xml vb.net linq
ノードのグルーピング
自己RESです．解決しました．  
まず前提条件がよくありませんでした．

> 終末の改行でグルーピングしたいのです．

XMLとして読んだ場合、行の先頭が要素ならvbCrLfは単独で出現しますが、例の`【補正をする者】<BR>`のようにテキストで行頭が始まる場合、`vbCRLf
+
【補正をする者】`というような形でテキストノードが出現してしまします．（`vbCrLf`は、前の行の物）つまりテキストファイルとして読むならまだしも、XMLで読む限り、改行はグルーピングのキーとは成り得ません．

代わりに、行末の`<BR/>`をキーにしてグルーピングしてみました．以下はそのサンプルコードです．

```

    Dim nodes As IEnumerable(Of XNode) = body.Nodes
    
    ' BODY以下のnodeをBR要素をキーにしてグルーピングする．
    Dim groupedNodes =
        From node In nodes
        Group node By key = getBrCount(node)
        Into Group
    ' 特許庁HTMLのBODY以下の行の処理
    For Each group In groupedNodes
        Dim lineNodes As List(Of XNode) = group.Group.ToList
        ' ここにグルーピングしたノード毎の処理を記述
    Next
    
    ...
    
    ' <BR/>を数える関数
    Function getBrCount(node As XNode) As Integer
        Return countBrElemNode(node, 0)
    End Function
    
    Function countBrElemNode(node As XNode, count As Integer) As Integer
        If node Is Nothing Then
            Return count
        ElseIf (node.NodeType = XmlNodeType.Element) AndAlso (CType(node, XElement).Name.LocalName = "BR") Then
            Return countBrElemNode(node.PreviousNode, count + 1)
        Else
            Return countBrElemNode(node.PreviousNode, count)
        End If
    End Function
    
```

もし改善の余地などありましたらご教示ください．
CC BY-SA 4.0
2019-02-21T10:23:58.820
52919
2019-02-21T10:23:58.820
9503
52871
answer