I've been looking for a Notepad++ plugin that can close HTML/XML tags after a slash just like the way Dreamweaver does for a long time.
The only things I could find(TextFX, XML Tools etc.) close the tags right after ">" is typed in, which was not what I wanted.
A couple days ago I found a plugin called Automation Scripts. It allows me to write scripts in C#, so I don't have to spend time learning how to write Notepad++ plugins.
So here you go:

//npp_shortcut Ctrl+Shift+Z

//Automation Scripts plugin needs to be installed for this to work
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Windows.Forms;
using NppScripts;

public class Script : NppScript
{
    public Script()
    {
        this.OnNotification = (notification) =>
        {
            if(notification.nmhdr.code == (uint)SciMsg.SCN_CHARADDED)
            {
                doInsertHtmlCloseTag((char)notification.ch);
            }
        };
    }

    public override void Run()
    {
        checkInsertHtmlCloseTag();
    }

    bool doCloseTag;

    void checkInsertHtmlCloseTag()
    {
        doCloseTag = !doCloseTag;
        Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_SETMENUITEMCHECK, Plugin.FuncItems.Items[this.ScriptId]._cmdID, doCloseTag ? 1 : 0);
    }

    string GetStartTagName(string input)
    {
        Regex regex=new Regex(@"<[A-Za-z][A-Za-z0-9]*[^>]*[^\/]>|<[A-Za-z]>");
        if(!regex.IsMatch(input)) return "";
        StringBuilder result=new StringBuilder();
        int i=1;
        while(input[i]!=' ' && input[i]!='>' & i<input.Length)
        {
            result.Append(input[i]);
            i++;
        }
        return result.ToString();
    }

    string GetEndTagName(string input)
    {
        Regex regex=new Regex(@"<\/[A-Za-z][A-Za-z0-9]*[^>]*>");
        if(!regex.IsMatch(input)) return "";
        StringBuilder result=new StringBuilder();
        int i=2;
        while(input[i]!=' ' && input[i]!='>' & i<input.Length)
        {
            result.Append(input[i]);
            i++;
        }
        return result.ToString();
    }
    
    string GetSelection()
    {
        IntPtr hCurrentEditView = Npp.CurrentScintilla;
        StringBuilder result=new StringBuilder();
        Win32.SendMessage(hCurrentEditView,SciMsg.SCI_GETSELTEXT,0,result);
        return result.ToString();
    }
    
    int FindNextTag(int pos)
    {
        IntPtr hCurrentEditView = Npp.CurrentScintilla;
        string pattern=@"<\/?[A-Za-z][A-Za-z0-9]*[^>]*[^\/]>|<\/?[A-Za-z]>";
        Win32.SendMessage(hCurrentEditView, SciMsg.SCI_SETSEL, pos, pos);
        Win32.SendMessage(hCurrentEditView,SciMsg.SCI_SEARCHANCHOR,0,0);
        return (int)Win32.SendMessage(hCurrentEditView,SciMsg.SCI_SEARCHPREV,(int)SciMsg.SCFIND_REGEXP,pattern);
    }
    
    void doInsertHtmlCloseTag(char newChar)
    {
        LangType docType = LangType.L_TEXT;
        Win32.SendMessage(Npp.NppHandle, NppMsg.NPPM_GETCURRENTLANGTYPE, 0, ref docType);
        bool isDocTypeHTML = (docType == LangType.L_HTML || docType == LangType.L_XML || docType == LangType.L_PHP);
        if (doCloseTag && isDocTypeHTML && newChar=='/')
        {
            IntPtr hCurrentEditView = Npp.CurrentScintilla;
            int currentPos = (int)Win32.SendMessage(hCurrentEditView, SciMsg.SCI_GETCURRENTPOS, 0, 0);
            char lastChar=(char)Win32.SendMessage(hCurrentEditView,SciMsg.SCI_GETCHARAT,currentPos-2,0);
            StringBuilder insertString=new StringBuilder();
            if(lastChar=='<')
            {
                int pos=currentPos;
                Stack<string> stack=new Stack<string>();
                string tag;
                while(true)
                {
                    pos=FindNextTag(pos);
                    if(pos==-1)
                    {
                        Win32.SendMessage(hCurrentEditView, SciMsg.SCI_SETSEL, currentPos, currentPos);
                        return;
                    }
                    tag=GetSelection();
                    if(tag[1]=='/')
                    {
                        stack.Push(GetEndTagName(tag));
                    }
                    else
                    {
                        tag=GetStartTagName(tag);
                        if(stack.Count==0) 
                            break;
                        else
                        {
                            string endTag=stack.Pop();
                            while(tag!=endTag && stack.Count>0)
                            {
                                endTag=stack.Pop();
                            }
                            if(tag!=endTag) break;
                        }
                    }
                }
                insertString.Append(tag+">");
                Win32.SendMessage(hCurrentEditView, SciMsg.SCI_BEGINUNDOACTION, 0, 0);
                Win32.SendMessage(hCurrentEditView, SciMsg.SCI_SETSEL, currentPos, currentPos);
                Win32.SendMessage(hCurrentEditView, SciMsg.SCI_REPLACESEL, 0, insertString);
                Win32.SendMessage(hCurrentEditView, SciMsg.SCI_SETSEL, currentPos+insertString.Length, currentPos+insertString.Length);
                Win32.SendMessage(hCurrentEditView, SciMsg.SCI_ENDUNDOACTION, 0, 0);
            }
        }
    }
}