This is what happens when you encounter such an interface during CRUD

<MachineModel machModelId="915432156" machModelName="Failure standard drive chain" machLayoutStatus="0">

 <item machModelId="915432156" itemtype="Seven" id="915432156 _1" name="Planet" bearingType="SRB/CARB" 

          bearingCompany="FAG" ftf="0.455" bsf="10.718" bpfo="13.64" bpfi="16.36" position_x="127" 

          position_y="150" speedRate="0.008350566967190259" left="8" right="16">


    </item>

 <item machModelId="915432156" itemtype="Seven" id="915432156 _2" name="Stars" bearingType="F-573602.NCF-WPOS" 

          bearingCompany="FAG" ftf="0.476" bsf="20.7" bpfo="30.9" bpfi="34.1" position_x="287" 

          position_y="150" speedRate="0.008350566967190259" left="16" right="3">


    </item>

</MachineModel>

Copy the code

The back end reads the XML configuration file back to me and asks me to get the location of the data on the tag on the page for presentation. Huh?

Temporarily no good ideas, then directly innerHtml then document. The getElementsByTagName.

When you’re done, it’s not very maintainable. I think it is possible to use vUE’s template parsing code for reference (copy), parse the template string, and get the data on the label.

regular

const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`// aaa- BBB // namespace

const qnameCapture = ` ((? :${ncname}\ \ :)?${ncname}) `// ? : indicates that matches are not captured

const startTagOpen = new RegExp(` ^ <${qnameCapture}`); // The re at the beginning of the tag captures the tag name

const endTag = new RegExp(` ^ < \ \ /${qnameCapture}[^ >] * > `); // Match

const attribute = /^\s*([^\s"'<>\/=]+)(? :\s*(=)\s*(? :"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))? /// Match attribute

const startTagClose = /^\s*(\/?) >/// The end of the matching tag can also be a self-closing tag, so />

Copy the code

Create the parseHtml function and create the helper function public HTML template string parameter in the form of a closure. Loop through HTML strings, handling different cases, and then intercept them.

 while (html) {

     let textEnd = html.indexOf('<')

     // Check whether it starts with <

     if (textEnd === 0) {

         // If it comes in, it could be the start tag or the end tag

         let startTagMatch = parseStartTag(html) 


         if (startTagMatch) {

             / / into the stack

             start(startTagMatch.tagName)

             // If the autism and tag are matched

             if (startTagMatch.autoEnd) {

                 end(startTags[startTags.length - 1])

             }

             continue // If the start tag matches, continue the next match

         }

         // Try to match the end tag

         let endTagMatch = html.match(endTag)

         if (endTagMatch) {

             advance(endTagMatch[0].length)

             end(endTagMatch[1])

             continue

         }

     }

     let text

     //
111 222


     if (textEnd >= 0) {

         text = html.substring(0, textEnd)

         advance(text.length)

         // Remove the string, no additional processing is required

     }

 }

Copy the code

The core function parses the start tag to get the required attributes

function parseStartTag({

    let start = html.match(startTagOpen)

    if (start) {

        const match = {

            tagName: start[1].// Matches the first group, which in this case is the tag name.

            attrs: []

        }

        advance(start[0].length) // start[0] indicates the matched result



        let endT, attr;

        // If the closing tag is not matched and the attribute is matched, then the attribute is parsed

        while(! (endT = html.match(startTagClose)) && (attr = html.match(attribute))) {

            advance(attr[0].length) // Remove the attribute

            match.attrs.push({

                name: attr[1].

                value: attr[3] || attr[4] || attr[5]

            })

        }

        stack.push({ tagName: match.tagName, attrs: match.attrs })

        // This deals with autism and tags

        if (endT[0].trim() === '/ >' && html.trim().match(startTagClose)) {

            let endTagMatch = html.match(startTagClose)

            if (endTagMatch) {

                advance(endTagMatch[0].length)

            }

            return { ...match, autoEndtrue }

        } else {

            advance(endT[0].length) // Remove > from the start tag

            return match

        }

    }

}

Copy the code

To match the start tag, you need to push

 function start(tagName{

     startTags.push(tagName)

 }

Copy the code

To match the end tag, you need to push the stack. The purpose of the start and end tag push is to check whether the matched end tag is the last matched start tag, otherwise an error will be reported. Self-closing tags are handled in the parseStartTag function.

function end(tagName{

    endTags.push(tagName)

    if (tagName === startTags[startTags.length - 1]) {

        startTags.splice(- 1)

    } else {

        console.error('Start tag does not match end tag')

        // Perform exception handling

    }

}

Copy the code

Intercepts an HTML string

 function advance(n{

     html = html.substring(n)

 }

Copy the code

The complete code

The processing result returned

Thank you for watching

If this article helped you, give it a thumbs-up.

Previous articles:

[I’m only seeing layer 3] Talk webpack again
Easy-to-understand implementation of custom promises that conform to the PROMISE A+ specification
Js asynchronous programming, eventLoop, message queue are what to do? What is a macro task and what is a microtask
Webpack4 Builds enterprise-level scaffolding