If you can piggyback off of the talent UI this looks a lot cleaner. But it does require Blizzard_ClassTalentUI to be loaded and opened once. This method does use the uncommitted changes.
for talentButton in ClassTalentFrame.TalentsTab:EnumerateAllTalentButtons() do
local nodeInfo = talentButton:GetNodeInfo()
if nodeInfo.currentRank and nodeInfo.currentRank > 0 then
print(string.format("%s %d/%d", talentButton:GetName(), nodeInfo.currentRank, nodeInfo.maxRanks))
end
end