精华内容
下载资源
问答
  • 今天我们在这里谈的tag标签的正确使用方法,就属于网站聚合页面优化的范凑。 tag标签优化是一种非常常见的网站优化手段。 百度百科的解释是:TAG标签是一种由您自己定义的,比分类更准确、更具体,可以概括文章...

       一个网站最为基本的页面主要可以分为两种类型,一种为聚合页面,一种为详情内容页面。今天我们在这里谈的tag标签的正确使用方法,就属于网站聚合页面优化的范凑。

       tag标签优化是一种非常常见的网站优化手段。 百度百科的解释是:TAG标签是一种由您自己定义的,比分类更准确、更具体,可以概括文章主要内容的关键词。tag标签是一种突出网站内容重要关键词或词条的表现,在如今的互联网中被很多的站点所应用有利于浏览者的快速查找与精准索引。我们可以将它定义成为一种灵活运用、快捷方便的内容分类方式,具体的设置方法根据自身网站内容进行规划。tag标签虽然没有具体的使用标准,但它给网站打开了很多的局限性变得更加开放,不会受到栏目分类的束缚在用户服务体验上有着不少的提高。也就是说,TAG标签就是一种快捷、方便的分类方式。网页的html编码中有几个meta标签:标题标签(Title Tag)、描述标签(Description Tag)、关键词标签(Keywords Tag)、publisher tag、copyright tag、robots tag 等等。运用TAG标签,可以使你发表的文章更容易被搜索到。

    TAG标签是一种由您自己定义的,比分类更准确、更具体,可以概括文章主要内容的关键词。(百度尤其喜欢)

      tag标签的正确用途是什么

    tag标签的作用对于网站优化和用户体验上来讲做出了很大的贡献,首先可以通过对它的设置将站点与之相互匹配的内容进行整理归纳当搜索时可集中呈现相关信息。其次能够使得站内链接更加强大内容匹配程度更高有效的在点击tag标签时跳转到关联页面,让网站内容变得丰富多彩有利于页面之间权重的相互传递。最后根据用户搜索习惯可将内容添加多个tag标签,降低用户的跳出率能够轻松的浏览到每个自己感兴趣的tag标签内

    展开全文
  • AprilTag详解-Python实现

    千次阅读 多人点赞 2020-08-07 23:42:29
    文章目录一、AprilTag简介二、AprilTag原理三、AprilTag图像生成四、OpenMV实现五、pupil-apriltags六、Python代码实现 一、AprilTag简介 AprilTag是一个视觉基准系统,可用于多种任务,包括增强现实,机器人和相机...

    一、AprilTag简介

    AprilTag是一个视觉基准系统,可用于多种任务,包括增强现实,机器人和相机校准。通过特定的标志(与二维码相似,但是降低了复杂度以满足实时性要求),可以快速地检测标志,并计算相对位置。它可以从普通打印机创建目标,AprilTag检测软件可以计算标签相对于相机的精确3D位置,方向和身份。AprilTag库在C中实现,没有任何外部依赖关系。它被设计为易于包含在其他应用程序中,并且可移植到嵌入式设备中。即使在手机级处理器上也可以实现实时性能。
    官网:https://april.eecs.umich.edu/software/apriltag.html

    展开全文
  • golang struct json tag的使用及深入理解

    千次阅读 2020-05-09 10:54:09
    struct json tag主要在struct与json数据转换的过程(Marshal/Unmarshal)中使用。本文主要介绍struct json tag的使用及探寻源码中的设计处理过程。

    一、sturct json tag的使用

    1.tag格式说明

    struct json tag主要在struct与json数据转换的过程(Marshal/Unmarshal)中使用。

    json的tag格式如下:

    Key type  `json:"name,opt1,opt2,opts..."`
    

    说明:

    • 变量必须是可导出的(Key首字母必须大写),否则会被忽略处理。
    • 没有json tag或者tag中name省略(但不能少了","),默认使用字段名。
    • name要注意命名的有效性。
    • opt1opt2等项为可选项,必须使用有限的几个限定的opt的一个或组合,如"omitempty""string",使用非限定的opt会发生错误。

    2.具体使用格式说明

    我们先介绍下源码文档中提供的几种使用方式:

    因Marshal与Unmarshal是相反的过程,两者规则是一致的,以下介绍中仅说明了Marshal时的处理。

    (1)不指定tag

    Field int // “Filed”:0

    不指定tag,默认使用变量名称。转换为json时,key为Filed。

    (2)直接忽略

    Field int json:"-" //注意:必须为"-",不能带有opts

    转换时不处理。

    (3)指定key名

    Field int json:"myName" // “myName”:0

    转换为json时,key为myName

    (4)"omitempty"零值忽略

    Field int json:",omitempty"

    转换为json时,值为零值则忽略,否则key为myName

    (5)指定key且零值忽略

    Field int json:"myName,omitempty"

    转换为json时,值为零值则忽略,否则key为myName

    (6)指定key为"-"

    Field int json:"-," // “-”:0

    此项与忽略的区别在于多了个”,“。

    (7)“string” opt

    以上提到的用法都是常见的,这个比较特殊。

    "string"仅适用于字符串、浮点、整数或布尔类型,表示的意思是:将字段的值转换为字符串;解析时,则是将字符串解析为指定的类型。主要用于与javascript通信时数据的转换。

    注意:
    仅且仅有"string",没有int、number之类的opt。即带"string" opt的字段,编码时仅能将字符串、浮点、整数或布尔类型转换为string类型,反之则不然;解码时可以将string转换为其他类型,反之不然。因为"string"有限制。

    Int64String int64 json:",string" // “Int64String”:“0”

    “string” opt的使用可以在Marshal/Unmarshal时自动进行数据类型的转换,减少了手动数据转换的麻烦,但是一定要注意使用的范围,对不满足的类型使用,是会报错的。

    猜下对string使用"string" opt的结果会是如何呢?

    Int64String string json:",string"

    我们在了解源码后解答。

    二、源码角度的设计处理过程

    一切的使用方式肯定在设计时就已限定,我们现在看看源码中的处理过程。
    在看实现的过程中,可以思考下使用的方式对不对,还有要注意的地方吗?
    对某些地方非常好的实现思路,我们也可以借鉴下,对以后的编程学习大有裨益。

    此处为了简洁,具体调用过程略过不讲,直接查看核心代码部分,有兴趣的话,可以查看下完整过程。

    1.typeFields

    在typeFields中详细的对上面提到的各种用法的tag做了处理,处理后的数据存入fileds,最后在进行编码。

    // typeFields returns a list of fields that JSON should recognize for the given type.
    // The algorithm is breadth-first search over the set of structs to include - the top struct
    // and then any reachable anonymous structs.
    func typeFields(t reflect.Type) structFields {
        // Anonymous fields to explore at the current level and the next.
        current := []field{}
        next := []field{{typ: t}}
    
        // Count of queued names for current level and the next.
        var count, nextCount map[reflect.Type]int
    
        // Types already visited at an earlier level.
        visited := map[reflect.Type]bool{}
    
        // Fields found.
        var fields []field
    
        // Buffer to run HTMLEscape on field names.
        var nameEscBuf bytes.Buffer
    
        for len(next) > 0 {
            current, next = next, current[:0]
            count, nextCount = nextCount, map[reflect.Type]int{}
    
            for _, f := range current {
                if visited[f.typ] {//已处理的过类型跳过
                    continue
                }
                visited[f.typ] = true
    
                // Scan f.typ for fields to include.
                for i := 0; i < f.typ.NumField(); i++ {
                    sf := f.typ.Field(i)
                    isUnexported := sf.PkgPath != ""
                    if sf.Anonymous {//内嵌类型的处理
                        t := sf.Type
                        if t.Kind() == reflect.Ptr {
                            t = t.Elem()
                        }
                        if isUnexported && t.Kind() != reflect.Struct {
                            // Ignore embedded fields of unexported non-struct types.
                            continue//非struct结构的不能导出的key直接跳过
                        }
                        // Do not ignore embedded fields of unexported struct types
                        // since they may have exported fields.
                    } else if isUnexported {
                        // Ignore unexported non-embedded fields.
                        continue//不能导出的key直接跳过
                    }
                    tag := sf.Tag.Get("json")
                    if tag == "-" {
                        continue//tag为"-"直接跳过
                    }
                    name, opts := parseTag(tag)
                    if !isValidTag(name) {
                        name = ""//包含特殊字符的无效name
                    }
                    index := make([]int, len(f.index)+1)
                    copy(index, f.index)
                    index[len(f.index)] = i
    
                    ft := sf.Type
                    if ft.Name() == "" && ft.Kind() == reflect.Ptr {
                        // Follow pointer.
                        ft = ft.Elem()
                    }
    
                    // Only strings, floats, integers, and booleans can be quoted.
                    quoted := false
                    if opts.Contains("string") {//此处为"string" opt的特殊处理,支持的类型如下:
                        switch ft.Kind() {
                        case reflect.Bool,
                            reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
                            reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
                            reflect.Float32, reflect.Float64,
                            reflect.String:
                            quoted = true
                        }
                    }
    
                    // Record found field and index sequence.
                    if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
                        tagged := name != ""
                        if name == "" {
                            name = sf.Name//未指定或者指定name无效的使用原field的name
                        }
                        field := field{
                            name:      name,
                            tag:       tagged,
                            index:     index,
                            typ:       ft,
                            omitEmpty: opts.Contains("omitempty"),//omitempty确认
                            quoted:    quoted,//是否支持"string" opt
                        }
                        field.nameBytes = []byte(field.name)
                        field.equalFold = foldFunc(field.nameBytes)
    
                        // Build nameEscHTML and nameNonEsc ahead of time.
                        //两种格式的构建
                        nameEscBuf.Reset()
                        nameEscBuf.WriteString(`"`)
                        HTMLEscape(&nameEscBuf, field.nameBytes)
                        nameEscBuf.WriteString(`":`)
                        field.nameEscHTML = nameEscBuf.String()
                        field.nameNonEsc = `"` + field.name + `":`
    
                        fields = append(fields, field)//存入fields
                        if count[f.typ] > 1 {
                            // If there were multiple instances, add a second,
                            // so that the annihilation code will see a duplicate.
                            // It only cares about the distinction between 1 or 2,
                            // so don't bother generating any more copies.
                            fields = append(fields, fields[len(fields)-1])
                        }
                        continue
                    }
    
                    // Record new anonymous struct to explore in next round.
                    nextCount[ft]++
                    if nextCount[ft] == 1 {
                        next = append(next, field{name: ft.Name(), index: index, typ: ft})
                    }
                }
            }
        }
    
        ...
    
        for i := range fields {
            f := &fields[i]
            f.encoder = typeEncoder(typeByIndex(t, f.index))//设置fields的encoder
        }
        nameIndex := make(map[string]int, len(fields))
        for i, field := range fields {
            nameIndex[field.name] = i
        }
        return structFields{fields, nameIndex}
    }
    

    2.encode

    func newStructEncoder(t reflect.Type) encoderFunc {
        se := structEncoder{fields: cachedTypeFields(t)}
        return se.encode
    }
    
    func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
        next := byte('{')
    FieldLoop:
        for i := range se.fields.list {
            f := &se.fields.list[i]
    
            // Find the nested struct field by following f.index.
            fv := v
            for _, i := range f.index {
                if fv.Kind() == reflect.Ptr {
                    if fv.IsNil() {
                        continue FieldLoop
                    }
                    fv = fv.Elem()
                }
                fv = fv.Field(i)
            }
    
            if f.omitEmpty && isEmptyValue(fv) {//"omitempty"的忽略处理,需要值为零值
                continue
            }
            e.WriteByte(next)
            next = ','
            if opts.escapeHTML {
                e.WriteString(f.nameEscHTML)
            } else {
                e.WriteString(f.nameNonEsc)
            }
            opts.quoted = f.quoted
            f.encoder(e, fv, opts)//根据具体类型的编码处理
        }
        if next == '{' {
            e.WriteString("{}")
        } else {
            e.WriteByte('}')
        }
    }
    

    以下以int类型intEncoder为例:

    func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
        b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
        if opts.quoted {//带有"string" opt添加引号
            e.WriteByte('"')
        }
        e.Write(b)
        if opts.quoted {
            e.WriteByte('"')
        }
    }
    

    对于数字类型,如果带有**“string”**则在写入正式值前后添加引号。

    对于字符串类型,如果带有**“string”**,原string值再编码时会添加引号,再对结果添加引号,则格式异常,因此需要先对原值进行编码。

    func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
        if v.Type() == numberType {
            numStr := v.String()
            // In Go1.5 the empty string encodes to "0", while this is not a valid number literal
            // we keep compatibility so check validity after this.
            if numStr == "" {
                numStr = "0" // Number's zero-val
            }
            if !isValidNumber(numStr) {
                e.error(fmt.Errorf("json: invalid number literal %q", numStr))
            }
            e.WriteString(numStr)
            return
        }
        if opts.quoted {
            sb, err := Marshal(v.String())//注意此处处理
            if err != nil {
                e.error(err)
            }
            e.string(string(sb), opts.escapeHTML)
        } else {
            e.string(v.String(), opts.escapeHTML)
        }
    }
    
    func (e *encodeState) string(s string, escapeHTML bool) {
        e.WriteByte('"')//添加引号
        start := 0
        for i := 0; i < len(s); {
            if b := s[i]; b < utf8.RuneSelf {//字符串中存在特殊的字符时的转义处理
                if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
                    i++
                    continue
                }
                if start < i {
                    e.WriteString(s[start:i])
                }
                e.WriteByte('\\')
                switch b {
                case '\\', '"':
                    e.WriteByte(b)
                case '\n':
                    e.WriteByte('n')
                case '\r':
                    e.WriteByte('r')
                case '\t':
                    e.WriteByte('t')
                default:
                    // This encodes bytes < 0x20 except for \t, \n and \r.
                    // If escapeHTML is set, it also escapes <, >, and &
                    // because they can lead to security holes when
                    // user-controlled strings are rendered into JSON
                    // and served to some browsers.
                    e.WriteString(`u00`)
                    e.WriteByte(hex[b>>4])
                    e.WriteByte(hex[b&0xF])
                }
                i++
                start = i
                continue
            }
            c, size := utf8.DecodeRuneInString(s[i:])
            if c == utf8.RuneError && size == 1 {
                if start < i {
                    e.WriteString(s[start:i])
                }
                e.WriteString(`\ufffd`)
                i += size
                start = i
                continue
            }
            // U+2028 is LINE SEPARATOR.
            // U+2029 is PARAGRAPH SEPARATOR.
            // They are both technically valid characters in JSON strings,
            // but don't work in JSONP, which has to be evaluated as JavaScript,
            // and can lead to security holes there. It is valid JSON to
            // escape them, so we do so unconditionally.
            // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
            if c == '\u2028' || c == '\u2029' {
                if start < i {
                    e.WriteString(s[start:i])
                }
                e.WriteString(`\u202`)
                e.WriteByte(hex[c&0xF])
                i += size
                start = i
                continue
            }
            i += size
        }
        if start < len(s) {
            e.WriteString(s[start:])
        }
        e.WriteByte('"')
    }
    

    在了解完源码的处理过程后,我们对之前提到的问题做个解答。对string类型的字段添加"string" opt,得到的是:

    Int64String string json:",string" // “Int64String”: "“1234"”

    三、总结

    本文主要从源码的角度说明struct json tag的为什么这么使用,以及使用时需要注意的地方。最后重复下重要的几点:

    • 字段必须可导出,tag才有意义
    • 忽略必须使用json:"-",不得带有opts,否则key将会变成"-"
    • "string" opt仅适用于字符串、浮点、整数及布尔类型,意思是可以将这些类型的数据Marshal为string类型,或者将string类型的数据Unmarshal为这些类型。
      请勿滥用,尤其是对已经是string类型的数据使用。
    展开全文
  • Tag文件和Tag标记的用法详解

    万次阅读 2018-09-22 13:51:18
    Tag文件和Tag标记 目录 1.为什么要使用Tag文件 2.Tag文件的结构 3.Tag文件的存储目录 4.Tag标记 5.Tag文件中常用的指令 1)tag指令 2)attribute指令 3)variable指令 4)taglib指令 5)include指令 6.Tag...

                                          Tag文件和Tag标记


    目录

    1.为什么要使用Tag文件

    2.Tag文件的结构

    3.Tag文件的存储目录

    4.Tag标记

    5.Tag文件中常用的指令

    1)tag指令

    2)attribute指令

    3)variable指令

    4)taglib指令

    5)include指令

    6.Tag文件的嵌套


    1.为什么要使用Tag文件

     1) 在Web应用中许多JSP页面都有相同的信息,如都需要相同的导航栏和尾页等。如果能把相同的信息都形成一种特殊的文件,而且各个JSP页面都可以使用这种特殊的文件,那么就能实现代码的复用,维护性就比较好了

    2)实现代码复用还有另外两种方式,include指令和include动作,那就来说说他们的不足吧,首先不论是include指令还是include动作处理的都是单一 的JSP文件,用户可以通过输入地址栏的方式来访问响应的JSP文件,这时候用户访问的JSP文件可能只是一个导航栏,这不是设计者希望看到的.include指令的耦合性太大,include动作虽然耦合性较小但是能放在Web服务目录的任意子目录中,不仅显的杂乱无章,还不利于管理和维护.

    3)使用tag文件就能很好的解决这一缺点,tag文件不仅能实现动态加载实现代码复用,还不能让用户直接访问,tag文件放在指定 的目录下,维护起来会比较方便(很多时候会让tag文件去处理数据,而JSP页面只是去显示数据,实现数据显示和数据处理分离,这样就比较便于维护了)


    2.Tag文件的结构

    Tag文件是扩展名为.tag的文件,其实与JSP文件差不多.在Tag文件中可以使用HTML标签,可以使用java脚本以及JSP动作和指令,还可以使用某些特殊的指令(后面会讲)


    3.Tag文件的存储目录

    Tag文件必须存在/WEB-INF/tags 文件夹下(不然会报错),存放目录如下图所示:


    4.Tag标记

    编写了一个Tag文件会对应生成一个Tag标记,Tag标记的格式为:

    <Tag 文件名字/>或

    <Tag 文件名字>

             标记体

    </Tag 文件名字>

    当JSP页面希望向Tag文件传递相应的信息时,可以使用标记体来传递,在Tag文件中通过<jsp:doBody/>来调用标记体

    一个Tag文件对应一个Tag标记,那么该目录下有若干个Tag文件就行成了一个库,在JSP页面要调用Tag文件,就要通过taglib指令来引入相应目录下的一个标记库,只有这样JSP页面才能调用相应的Tag文件并动态执行该Tag文件

    <%@taglib prefix="前缀" tagdir="自定义标记库的位置"%>

    注意:使用前缀可以区别不同标记库下相同名字的标记文件

    如:调用/WEB-INF/tags/math/random.tag文件就可以在JSP页面中这样写

    <%@taglib prefix="math" tagdir="/WEB-INF/tags/math/"%>来引入标记库

    之后可以<math:random/>或者<math:random>标记体</math:random>来调用了并执行相应tag文件了


    5.Tag文件中常用的指令

    1)tag指令

    1.body-content属性

    body-content属性的值有empty、tagdependent、scriptless,其默认值是scriptless

    empty:当body-content属性的属性值为empty时,JSP页面中必须使用没有标记体的tag标记,<Tag 文件名字>

    tagdependent:当body-content属性的属性值为tagdepentdent时,JSP页面通过标记体传来的信息全部按纯文本处理

    scriptless:当body-content属性的属性值为scriptless时,标记体中不能使用Java程序块,可以使用文本,EL表达式,一个自定义标记,一个动作

    2.language属性

    其属性值只支持java

    3.import属性

    引入java核心类包,可以在Tag文件中使用某些类,跟导包没什么区别就不说了

    4.pageEncoding属性

    Tag文件的编码属性,其默认值是ISO-8859-1

    2)attribute指令

    Tag文件充当着代码复用的角色,如果能像include动作一样向Tag文件传递数据,这会让Tag文件的功能更加强大,这当然是可以的,在Tag文件中有attribute指令,其语法格式如下:

    <%attribute name="对象名字" required="true"|"false" type="对象的类型"%>

    attribute指令中name属性是必须的,该属性是引用一个对象的名字.required为true时必须给其传值,为false时可以传可以不传,type为该对象的类型,默认为java.lang.String类型,可以改为其他类型,但要注意的是,必须对象类型必须带有包名,如不能简写为type="Integer"必须是type="java.lang.Integer"

    需要注意的是:在Tag文件中不可以再定义和attribute指令中name属性指定的对象具有相同名字的变量,否则将隐藏attribute指令中的对象,使其失效(可以通过观察源码发现,attribute中的变量其实在Tag文件中一个成员变量)

    下面是使用attribute指令的一个例子计算三角形面积的例子:

    JSP页面:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@taglib prefix="kai" tagdir="/WEB-INF/tags/geng" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'MyJsp.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
      <form action="" method="post">
      边长A: <input type="text" value="" name="a"><br>
      边长B: <input type="text" value="" name="b"><br>
      边长C: <input type="text" value="" name="c"><br>
      <input type="submit" value="Enter">
      </form>
      <br>
      <%
      		if((request.getParameter("a")!=null && request.getParameter("a")!="")
      			&& (request.getParameter("b")!=null && request.getParameter("b")!="")
      			&& (request.getParameter("c")!=null && request.getParameter("c")!="") ){
       %>
      	<kai:Addsum a="<%=Double.valueOf(request.getParameter(\"a\"))%>" b="<%=Double.valueOf(request.getParameter(\"b\"))%>" c="<%=Double.valueOf(request.getParameter(\"c\"))%>">
      	</kai:Addsum>
      	<%}%>
      </body>
    </html>
    

    tag文件:

    <%@tag import="java.text.DecimalFormat"%>
    <%@tag pageEncoding="UTF-8" body-content="scriptless"%>
    <%@attribute name="a" required="false" type="java.lang.Double"%>
    <%@attribute name="b" required="false" type="java.lang.Double"%>
    <%@attribute name="c" required="false" type="java.lang.Double"%>
    <html>
    	<head>
    	</head>
    	<body>
    		以下是调用Tag文件的效果:<br>
    		这是一个Tag文件,负责计算三角形的面积.<br>
    		JSP页面传递过来的三条边:<%=a%>,<%=b%>,<%=c%><br>
    		<%
    			DecimalFormat format = new DecimalFormat("0.00");
    			if(a+b>c && a+c>b && b+c>a){
    				double p = (a+b+c)/2;
    				out.print("三角形的面积: "+format.format(Math.sqrt(p*(p-a)*(p-b)*(p-c))));
    			}else{
    				out.print("<br>"+a+" "+b+" "+c+" 不能构成三边");
    			}
    		 %>
    	</body>
    </html>

     

    3)variable指令

    Tag文件通过使用attribute指令JSP页面可以向Tag文件传递数据.在某些Web设计中,不仅需要向其传递数据,还需要他返回某些数据进行特殊处理.比如多个JSP页面需要Tag文件处理一些数据,但是不需要显示,因为每个JSP页面需要特殊的显示,这时候就可以使用variable指令,variable指令语法格式如下:

    <%variable name-given="对象名字" variable-class="对象类型" scope="有效范围"%>

    name-given:用来指定对象的名字,要符合命名规则

    variable-class:指定的类型,注意需要打全包名,不能进行简写

    scope中有三个属性值:

                    1.AT_BEGIN,在使用JSP页面标记的时候就可以使用该对象

                     2.NESTED,只能在标记体中使用该对象

                     3.AT_END,只能在标记体结束后使用该对象

    Tag通过jspContext.setAttribute("对象的名字",对象的引用);把对象名字和对象引用存储到内置对象jspContext中,JSP页面才能使用该对象

    4)taglib指令

    和JSP页面一样,Tag文件中也可以使用taglib指令来调用其他的tag文件,操作一样

    5)include指令

    其用法与JSP页面中的include指令差不多,这里就不说了


    6.Tag文件的嵌套

    在使用Tag标记时,可以带有标记体,标记体还可以是一个Tag标记,这就实现了Tag标记的嵌套


    转载请注明出处

    展开全文
  • Apriltag使用之二:方位估计(定位)

    千次阅读 热门讨论 2019-10-25 14:48:21
    Apriltag中计算的Homography 首先,在进行apriltag码检测时,如果检测到会一并计算出图像上apriltag码四个角点对应的homography矩阵,这个homography将这些点映射到到标准的(-1,1),(1,1),(1,-1),(-1,-1)顶点。在...
  • sublime插件tag

    千次下载 热门讨论 2014-09-19 21:27:35
    在sublime2的安装目录下新建Data文件夹,在Data文件夹下新建Packages文件夹,在Packages下放入tag。重启即可。
  • 但无论采用这两种的任何一种,都是可以在同一个topic下,通过tag来进行业务区分的。 网上有很多分析相关使用方式的文章,虽然分析的结果都是“不可以”,但我们可以通过其他的一些方案来进行解决。 自主搭建的...
  • 织梦dedecms TAG标签调用汇总

    千次阅读 2019-02-13 16:27:49
    TAG标签是一种由您自己定义的,比分类更准确、更具体,可以概括文章主要内容的关键词,合理的运用TAG标签,可以使你发表的文章更容易被搜索到。 很多网站的首页、列表页和文章页调用的TAG关键词是带超链接,这样...
  • 自定义控件之TagGroup

    千次阅读 2017-07-09 23:41:17
    当一行addView(tag)的时候超过了最外层的宽度,则需要另起一行! 继承ViewGroup 继承ViewGroup的情况,比较麻烦。需要自己处理onMeasure()和onLayout() ! 自定义一套TagGroup 需要注意的地方...
  • git下载指定tag版本

    千次阅读 2020-03-23 17:07:04
    a v1.4 -m 'version 1.4' git push origin v1.4 注意:v1.4在tag和push命令里面要一致 --下载指定版本的git git tag #查看所有tag标签 git checkout v1.5 #变成指定版本的git状态 或者使用 git checkout a727b94 ...
  • Apriltag原理简介及源代码

    万次阅读 多人点赞 2019-05-16 13:41:05
    概要AprilTag视觉定位Python实现AprilTag过程AprilTag边缘检测四边形检测编码与解码实现代码 AprilTag视觉定位Python实现 AprilTag是一个视觉基准库,在AR,机器人,相机校准领域广泛使用。通过特定的标志(与二维码...
  • dicom文件tag详解

    万次阅读 多人点赞 2017-07-14 18:00:33
    dicom文件tag详解Dicom全称是医学数字图像与通讯,这里讲diocm格式文件的tag标记做详细解读。 dicom中文协议文档:http://download.csdn.net/download/wenzhi20102321/9897014dicom文件结构:dicom文件,整体结构...
  • Android Camera HAL3 Vendor Tag 定制私有化

    千次阅读 2019-03-28 15:32:20
    最近需要搞个私有参数下来作为apk 设置开关使用,想到之前HAL1 的使用过增加 Parameters 来实现,所以有自然想到了现在的 vendor tag,下面是android source code 的使用,可以作为例子。 其实mtk自己已经实现了一套...
  • go Tag详解

    千次阅读 2019-08-27 11:51:10
    我们可以通过Tag来增强结构体的定义,Tag会带上一些meta信息,在本文中我们将通过几个例子来深入了解Tag的用法。 结构 Struct是由一组field组成,每个field包括了名字(可选)和字段类型 package main import "fmt" ...
  • AprilTagTag识别,定位以及跟随

    千次阅读 2019-08-20 18:03:30
    AprilTagTag识别,定位以及跟随 Author lifuguan E-mail 1002732355@qq.com 开源链接 https://github.com/lifuguan/AprilTag_Localization 个人博客 ...
  • XMLTag详解

    千次阅读 2017-02-05 12:58:39
    无论是XMLAttribute还是XMLTag类,都有OSQueueElem fElem成员变量。该变量在构造函数中fElem = this,默认调用了OSQueueElem的构造函数:使得fEnclosingObject指向this。也就是说,XMLAttribute中的fElem::...
  • IntelliJ idea——》创建tag、删除tag

    千次阅读 2018-11-08 10:27:35
    版权声明:本文为博主原创文章,无需授权即可转载,甚至无需保留以上版权...IntelliJ idea创建tag1、找到git命令选项2、填写tag3、提交tag 1、找到git命令选项 右击项目——》Git——》Repository——》Tag 2...
  • shell:获取git当前分支或tag

    千次阅读 2019-09-01 11:14:07
    shell下如何获取git的当前所在分支名或tag呢? 为了解决这个小问题,我之前是走了弯路的,之前我简单的想法就是解析git branch输出的内容从中获取 分支或tag名。 如下代码, # 返回$1指定的git项目的当前分支(branch)...
  • 网站优化tag的正确用途,利用tag页面将事半功倍 网站tag栏目的描述调用文章描述的方法,最近着手新站www.uimou.com的优化,以为一直被我忽略的tag页面也在此次重新提上日程。本次在分享tag页面的优化方式主要是前段...
  • RocketMQ(03)——通过Tag对消息分类

    千次阅读 2019-12-28 19:38:30
    通过Tag对消息分类 RocketMQ建议一个业务系统只使用一个Topic,不同类型的消息通过tag来区分。tag可以在构造Message的时候指定,下面代码就指定了发送的消息的tag都为tag0。 @Test public void sendWithTag() throws...
  • git tag 标签简介 1、git tag --list 列出所有的标签 2、git tag <your_tag_name> 创建一个标签 3、git tag -a <your_tag_name> -m ‘your_tag_description’ 创建一个带有注释的标签 4、git show <...
  • git tag及推送tag到远端服务器

    千次阅读 2019-05-14 14:57:55
    https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE https://blog.csdn.net/github_27263697/article/details/79563949 1.列出现有标签 git tag v0.1 ...git tag -l "v1....
  • mp3tag批量编辑

    千次阅读 2019-07-06 20:04:40
    通过代码批量修改mp3tag属性(mp3文件中这些属性统称为 mp3tag ) package com . join . tools . mp3 ; import com . mpatric . mp3agic . * ; import java . io . File ; public class Mp3Tools ...
  • tag 组件的内容 在手机移动端上面的时候,文字的字体会有向上偏移的情况,所以在在组件方面我没有使用height,而采用了padding,利用padding来进行是文字居中(文字普遍的向上偏移2px) <template> <div...
  • a-tag v-for="(item,i) in modelProps.prdSelData" :key="i" closable @close="tagBtnCloseFunc(item)" @click="tagBtnClickFunc(item)" :style="i==modelProps.prdSelData.length-1?'background-color:#189
  • GIT删除本地tag和远程tag

    千次阅读 2020-02-15 12:57:25
    tag test为例,这个tag已经同步到远程,但是现在发现了一个问题,需要撤回该tag,git命令如下: 删除本地tag: git tag -d test 删除远程tag: git push origin :refs/tags/test 也可以在vs2017+自带的git...
  • vue结合elementUI实现tag多标签页

    千次阅读 2020-12-26 23:06:06
    vue结合elementUI实现tag多标签页 点击左侧菜单栏,会打开一个相应的tag标签页 点击tag标签可以在不同tag之间切换 如图: 以上图片的布局如下: <el-container> <BaseAside /> <el-main> &...
  • 细说VLAN之untag和tag

    千次阅读 2020-03-24 23:34:02
    二、理论基础 端口的出和入是针对交换机而言的,即数据帧进入交换机即为进入某个端口, access:接入链路: 入方向:收到不带tag数据,打上本接口的PVID(port VLANID) 出方向:发出时,带tag的数据去掉tag(只有...
  • 用Python来获取DICOM数据TAG信息

    千次阅读 2021-04-29 14:20:19
    Python读取DICOM文件的 TAG信息。 任何你想要的的,只要它有,就能读
  • Unity代码添加设置Tag或Layer

    千次阅读 2020-01-13 17:09:41
    Unity代码设置Tag或Layer描述注意代码 描述 Unity中设置Tag和Layer的方法,大家都知道,步骤较为繁琐。有时将一些代码复用到其他项目时,经常会出现Tag或Layer,不存在或找不到的情况。我便找到了这几个通过代码添加...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,129,725
精华内容 451,890
关键字:

tag