修改xml文件标签名称、筛选xml文件中的指定标签

在模型训练和数据标注的时候经常出现一些需要修改标签信息的情况,或者说想要单独整理一类的标签出来审核或者训练,通常我们用labelimg来一张张图片审核修改是非常吃力的,所以我写了一个脚本方便大家对标签信息做一些自动化操作。请注意使用的时候需要在要保存的文件夹路径下创建名为img和xml的空文件夹
这篇文章主要解决两个需求:
1、在整个数据集中将一个标签集合的图片和标注筛除出来,比如在大数据集中有ABC三个类,如果此时我想要将B类的图片和标注单独分出来并且选出来的标注中会删除A和C,可以使用下面这个脚本:

# 从原始img和xml中筛选拥有目标label的img和xml到新路径下,并且新xml中只保留我要的标签
import os
import shutil
from pathlib import Path
import xml.etree.ElementTree as ET

output_dir = r'new_path'  # 筛选修改后的新xml保存路径
input_dir = r'raw_path'  # 原始的xml文件夹

# 可以自定义自己想要筛选的标签, 
# large_labels = ['A', 'B', 'C']
target_labels = ['B']. # 只需要打标签集合的子集就行了,比如这里就只会将带有B标签的图片选出来并且对应的标注中不会有A、C的标签信息

# 初始化路径
input_dir_path = Path(input_dir)
output_dir_path = Path(output_dir)
new_xml_dir = output_dir_path / 'xml'
raw_xml_dir = input_dir_path / 'xml'
new_img_dir = output_dir_path / 'img'
raw_img_dir = input_dir_path / 'img'

n = 0  # 统计筛选的数量
img_names = []  # 记录筛选出来的图片名称
for xml in os.listdir(raw_xml_dir):
    raw_xml_path = str(raw_xml_dir / xml)
    new_xml_path = str(new_xml_dir / xml)  # 后面保存修改后的xml文件时用到
    tree = ET.parse(raw_xml_path)
    root = tree.getroot()
    print(f'处理{raw_xml_path}中')
    for obj in root.findall('object'):
        name = obj.find('name').text
        if name not in target_labels:
            root.remove(obj)
    # 检查标签是否全部删掉,如果标签集不为空则保存
    if root.findall('object'):
        n += 1
        img_names.append(xml[:-4])
        tree.write(new_xml_path)

# 复制对应图片到新路径下
for img in os.listdir(raw_img_dir):
    raw_img_path = str(raw_img_dir / img)
    new_img_path = str(new_img_dir / img)
    if img[:-4] in img_names:
        shutil.copy(raw_img_path, new_img_path)
print('图片拷贝完成。')
print(f'总计挑选出{n}组img和xml。')

2、如果我在训练的时候发现有标注中有标签名写错了导致训练报错或者说我想要在原始标签文件中将一类标签名进行修改可以使用下面的脚本:

# 从原始img和xml中筛选拥有目标label的img和xml到新路径下,并且新xml中修改标签名称
import os
import shutil
from pathlib import Path
import xml.etree.ElementTree as ET

output_dir = r'new_path'  # 筛选修改后的新xml保存路径
input_dir = r'raw_path'  # 原始的xml文件夹

# 新旧标签名称映射字典
label_pair = {'A': 'B'}. # 将A标签改成B

# 初始化路径
input_dir_path = Path(input_dir)
output_dir_path = Path(output_dir)
new_xml_dir = output_dir_path / 'xml'
raw_xml_dir = input_dir_path / 'xml'
new_img_dir = output_dir_path / 'img'
raw_img_dir = input_dir_path / 'img'

n = 0  # 统计筛选的数量
img_names = []  # 记录筛选出来的图片名称
for xml in os.listdir(raw_xml_dir):
    raw_xml_path = str(raw_xml_dir / xml)
    new_xml_path = str(new_xml_dir / xml)  # 后面保存修改后的xml文件时用到
    tree = ET.parse(raw_xml_path)
    root = tree.getroot()
    print(f'处理{raw_xml_path}中')
    for obj in root.findall('object'):
        name = obj.find('name').text
        if name in label_pair:
            obj.find('name').text = label_pair[name]
    # 如果标签集不为空则保存
    if root.findall('object'):
        n += 1
        img_names.append(xml[:-4])
        tree.write(new_xml_path)

# 复制对应图片到新路径下
for img in os.listdir(raw_img_dir):
    raw_img_path = str(raw_img_dir / img)
    new_img_path = str(new_img_dir / img)
    if img[:-4] in img_names:
        shutil.copy(raw_img_path, new_img_path)
print('图片拷贝完成。')
print(f'总计处理{n}组img和xml。')

注意:我这里为了防止误操作都是将数据修改之后保存到一个新的路径而不是替换原来的文件,如果需要可以自己修改一下代码。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
第1篇 Excel基本功能 • 冻结窗格 • 名称框定位 • 区域名称显示 • 多表区域设置格式 • 自动填充功能 • 数据的格式化 • 设置数字格式 • 数据类型转换 • 自定义数字格式 • 数据的填充复制 • 数据的查找替换 • 格式查找替换 • 数据含通配符的查找 • 表格边框设置立体效果 • 如何在Excel自动扩展格式 • 如何在Excel自动套用格式 • 自定义工具栏 • 非连续区域集打印 • 设置打印标题 第2篇 使用公式和函数 • 使用简单公式计算产品销售利润 • 使用相对和绝对引用计算产品销售额与利润 • 多表区域引用 • 利用混合引用制作九九乘法表 • INDEX函数和SUMIF函数特殊情况下的易失性 • Excel公式结果的检验和验证 • 创建Excel动态名称实现采购数据的动态引用 • 成绩检索表-Excel名称代替引用 • Excel图表使用名称 • 相对引用和混合引用定义名称 • 借用“列表”定义动态名称 • Excel工作表复制的名称问题 • 利用文本比较标识首次出现的记录 • 更改数据字母大小写 • 利用MID 函数提取身份证号码的8 位生日数字 • 使用文本提取函数进行数字分列 • 使用查找函数拆分空格分隔的数据 • 实现EAN-13条码的校验位的算法 • 利用文本查找函数进行模糊查找 • 利用SEARCHB 函数分离全半角字符 • 利用FIND 函数提取连续数字 • 统计开奖号码不重复数字个数 • 取得零件规格的最后序号 • 利用TEXT函数格式化设备编号 • 从身份证号码提取员工的生日信息 • 使用TEXT 函数显示文格式的年份 • 将数值转换为商业发票文大写金额 • 生成文大写金额 • 利用CELL 函数取得动态工作表标签名称 • 利用MOD 函数生成数字校验码 • 利用MOD 函数实现培训反馈表票数求和 • 利用取舍函数生成重复个数的自然数序列 • 按照特定条件进行取舍计算 • 利用取舍函数解决四舍六入问题 • 产生50~100 的随机整数 • 利用随机函数仅生成数字和字母 • 利用随机函数实现考试座位随机编排 • 日计帐的余额累计 • 计扣个人所得税 • 统计月末考试大于等于平均分的总分 • 利用CHAR 函数生成A~Z 序列 • 利用DATE 函数生成指定日期 • 利用运算符计算日期相差天数 • 利用日期函数计算公民年龄 • 利用日期函数计算员工退休日期 • 计算上月的天数 • 计算目标日期所在季度的最后一天 • 返回目标日期是全年的第几天 • 判断是否为闰年 • DATEDIF函数基本用法 • 利用日期函数计算员工工龄 • 计算指定日期的星期值 • 计算上月月末日期的星期 • 指定某月的第几周的天数 • 推算出指定年份的母亲节和父亲节日期 • 计算上个月的考勤天数 • 计算基金赎回入账日期 • 加班时间的累加 • 计算车间工人工时 • 员工加班时间的舍入计算 • 使用VLOOKUP 函数进行员工信息查询 • 利用HLOOKUP 函数查询产品月销售量 • 查找某员工是否登记在员工信息表 • 判断员工公积金是否重复提缴 • 查询申购基金的申购手续费 • 从成绩明细表查询学员总成绩 • 利用LOOKUP 函数实现无序查询 • 取得最后非空单元格数值 • 利用行列号函数生成永恒的序号 • 查询员工信息表所有人事信息 • 利用INDIRECT函数动态统计产品销量 • 利用OFFSET函数产生区域引用 • 利用INDEX函数隔行提取数据 • 多条件组合查询资料 • 利用INDEX函数结合MATCH函数进行向左查找 • 实现根据学员成绩查询等级 • 确定工资单最后一名员工的位置 • 根据工资表生成工资条 • 利用CHOOSE函数重新生成内存数组 • 利用查找函数进行多表数据标识 • 实现多区域联合判断求值 • VLOOKUP函数实现向左查询 • 从生产配件编号提取连续的数字编码 • 利用MATCH 函数提取连续数值 • 查询并汇总各产品销售额 • 利用MATCH函数汇总最后3 天的产品销售额 • 利用RANK函数实现按班级进行动态排名 • 利用COUNT函数统计培训反馈表的平均票数 • 动态引用商品进货明细表 • 统计培训课程表各部门的授课数 • 统计进货量大于5小于10的型号数量 • 标注各种水果第1次出售日期 • 查询重复输入员工身份证 • COUNTIF函数使用通配符统计示例 • 汇总指定公司的产品季度销量 • 统计二季度手机销量情况 • 利用SUMIF 函数实现多表汇总 • 按区间统计数值个数 • 学员英语成绩分段统计人数 • 计算比赛评分表频率最高的分值 • 利用极值函数限定销售价格 • 取得不重复的第2 个最低报价 • 统计各科成绩大于等于平均分的总平均分 • 计算体操比赛的选手得分 • 统计年度培训完成情况表 • 在筛选条件下生成连续序号 • 按学员成绩进行排名 • 根据比赛成绩实现国式排名 • 根据学员成绩的百分比占比划分等级 • 统计购买商品的不重复VIP 用户数 • 商品月度销量统计汇总 • 统计足彩数据最多连胜场数 • 单利与复利的比较 • 终值系数和现值系数 • 普通年金终值和现值的计算过程 • 预付年金终值和现值的计算过程 • 递延年金终值和现值的计算过程 • 年金终值系数表和年金现值系数表 • 名义利率与实际利率 • 整存整取 • 零存整取(一) • 零存整取(二) • 房屋的价值(一) • 房屋的价值(二) • 买卖房屋的利润率 • 投资经营房屋的利润率 • 多久才能拥有100万(一) • 多久才能拥有100万(二) • 孩子上大学的学费(一) • 孩子上大学的学费(二) • 孩子上大学的学费(三) • 利用Excel财务函数计算住房按揭还款计划 • 相同间隔时间序列的现金流量净现值 • 相同间隔时间序列的现金流量内部收益率 • 不规则时间序列和现金流量的净现值与内部收益率 • 考虑融资成本和再投资收益的内部收益率 • 直线折旧法 • 年限总和折旧法 • 固定余额递减折旧法 • 双倍余额递减折旧法 • 可变余额递减法的累计折旧 • 累计到第2年第3 季度期的累计折旧 • CONVERT函数的应用 • 使用CONVERT函数应注意正确书写 • 多单元格数组公式计算销售金额 • 单个单元格数组公式计算销售总额 • 两个一维数组的乘法运算 • 两个一维数组的连接运算 • 使用两个一维数组构造二维数组 • 部门评价等级转换 • 使用MMULT 函数计算产品结构指数 • 产生1-10 的自然数垂直序列和水平序列 • 等比例构造一维循环数组 • SUMIF函数对产品产量进行逐行汇总 • 利用MMULT函数实现数组累加 • 将销售明细表合并单元格填充地区名称 • 将二维数组按列转换为一维数组 • 数组公式实现单条件求和 • 计算一周内存采购的平均价格 • 统计各品牌的商品销量汇总 • 利用COUNT函数代替SUM 函数统计不重复记录 • 标识零件规格号的非法数据 • 将文大写日期转换成日期序列 • 实现按日期和客户名查询数据 • 按条件实现总表拆分到分表 • 按比赛成绩进行降序排列 • 对员工信息表员工姓名排序 • 从培训课程安排表提取讲师部门 • 从商品明细表提取唯一品牌名称 • 根据商品和品牌确定唯一品牌名称 • 多维引用示例的数据来源 • 利用INDIRECT函数返回对多表区域的引用 • 求金额最大的费用项目 • 提取无重复的水果清单 • 计算按原始股折算的某股票最高价格 • 计算用餐记录分摊实例 • 计算最好成绩和的最优成绩实例 • 跨多表条件求和 • 宏表函数取得工作表标签名称 • 标识商品销售表红色字体的记录 • 按照商品采购表的数值格式显示查询结果 • 提取指定单元格的公式表达式 • 根据立方体指定参数计算公式结果 • 提取固定字符间隔的零件规格号 第3篇 创建图表和图形 • 图表种类 • 柱形图 • 条形图 • 折线图 • 饼图 • XY散点图 • 面积图 • 圆环图 • 雷达图 • 曲面图 • 气泡图 • 股价图 • 圆柱图、圆柱图和棱锥图 • 自定义图表类型 • 线-柱图 • 两轴折线图 • 对数图 • 组合图 • 创建自定义图表 • 添加误差线 • 设置轴格式 • 分类坐标轴标签 • 空单元格的绘制方式 • 设置单个数据点格式 • 设置透明色 • 多工作表数据作图 • 添加趋势线 • 设置三维图表 • 数字条件格式 • 设置坐标轴的交点 • 使用次坐标轴 • 图表上的文本框 • 图表的组合 • Microsoft Graph图表 • 图表转为图片 • 设置自动筛选 • 添加辅助行 • 定义名称 • 数据透视图 • 使用Excel VBA • 添加水平线 • 添加垂直线 • 复合饼图 • 等高线图 • 直方图 • 排列图 • 控制图 • 动态对比图 • 动态股票图 • XY散点折线图的内插值计算 • 自选图形种类 • 插入自选图形 • 添加文本 • 自选图形绘制线条和连接符 • 旋转和翻转 • 对齐和分布 • 自动靠齐 • 设置叠放次序 • 设置组合 • 设置阴影 • 设置三维效果 • 设置超链接 • 制作室内平面图 • Excel图形 • Excel工作表背景 • 插入图片到Excel工作表 • 图片的调整 • 裁剪图片 • 旋转图片 • 设置图片的透明色 • 插入动态图片 • 制作组织结构图 • 流程图 • 循环图 • 射线图 • 棱锥图 • 维恩图 • 目标图 • 创建艺术字 • 插入剪贴画 第4篇 使用Excel进行数据分析 • 数据列表的实例 • 使用记录单为数据列表命名动态名称 • 数据列表按行排序 • 含有公式的数据排序 • 简单排序的例子 • 自定义排序 • “关系或”条件的高级筛选 • “关系与”条件的高级筛选 • 利用高级筛选选择不重复的记录 • 三个“关系或”条件的高级筛选 • 使用计算条件的Excel高级筛选 • 同时使用“关系与”和“关系或”的Excel高级筛选 • 创建分类汇总 • 列表 • Excel分列功能 • 使用“导入外部数据”功能导入标准工时数据 • Microsoft Query检索数据源 • 销售数据清单 • 定义名称创建动态数据透视表 • 分页显示数据透视表 • 使用数据列表功能创建动态数据透视表 • 按日期或时间项组合 • 按数字项组合 • 指定项组合 • 创建计算字段 • 添加下计算项 • 获取Excel数据透视表数据 • 创建复合范围的Excel数据透视表 • 数据透视图 • 模拟运算表 • 单变量求解 • 规划求解 • 分析工具库 第5篇 使用Excel的高级功能 • 设置单元格数值条件 • 设置公式条件 • 复制删除条件格式 • 应用示例 • 优先顺序 • Excel数据有效性允许的条件 • 定位复制删除Excel数据有效性 • 数据有效性的高级应用 • 数据有效性的高级应用_多表不重复输入 • 分级显示 • 合并计算 第6篇 使用Excel进行协同 • Excel单元格引用建立链接统计奖金总额 • 超链接实例 • 创建Excel动态超链接 • 发布(不)具有交互性的网页_Excel的交互性 • 创建Web查询 • Excel和ASP • Excel与XML数据 • Excel与其他应用程序共享数据 • 使用Excel工作组 第7篇 Excel自动化 • 录制宏 • VBA语言基础 • 与Excel进行交互 • Excel的自定义函数 • 如何操作Excel工作簿、工作表和单元格 • 工作表的Change事件 • 工作表高亮显示行和列 • 文件保存提醒 • 关闭工作簿是恢复Excel默认设置 • 设置Excel工作簿打开时的界面 • VBA事件激活的顺序 • VBA事件的激活与禁止 • 插入命令按钮 • 使用命令按钮设置单元格格式 • 使用复选框控件制作多选调查问卷 • 使用选项按钮控件制作单项调查问卷 • 使用组合框控件制作调查问卷 • 使用文本框控件快速录入三位数字 • Excel工作簿插入用户窗体 • 在用户窗体插入控件 • 为窗体控件添加事件代码 • 用户窗体的QueryClose事件和Terminate事件
DWR.xml配置文件说明书 1、 建立dwr.xml 配置文件 任何一个dwr.xml的文件都需要包含DWR DOCTYPE的声明行,格式如下: 整个配置文件的大体结构如下: ... 有几个术语有必要理解,参数叫做converted,远程Bean叫做created.如果远程Bean A有个方法A.blah(B),那么你需要为A建立一个created,为B建立一个converted. 配置文件init部分声明那些用于建立远程bean和在方法调用转换bean的类.这部分是可选择性配置的,多数情况下可以不必使用它,如果你想定义一个新的creator或者converter那么就必须在部分声明,but do double check on the ones that are currently available first. 在init部分的作用是告诉DWR一些类实例和关于这些类怎样运行的信息.实际上并不会使用.这有点向java的import语句,多数类在使用之前需要引入,但引入了类并不意味着这些在使用,每个creator和converter需要有个id属性来允许以后进行引用. 配置文件的allow部分定义哪些类可以建立和转换,每个被准许的类都可以有一个'create'或者'convert'配置行.下面列出的类的转换在默认情况下不需要进一步的设置. 1、所有基本类型,boolean,int,double等等 2、基本类型的对象形式实现的类,Boolean,Integer等等 3、java.lang.String 4、java.util.date 和三个SQL形式的派生类 5、以上所有类型的数组形式 6、以上所有类型的集合,List,Set,Map(有些局限性) However nothing is added to the list of classes that can be created (i.e. put up for remoting) without you declaring it. 2、 The Converters DWR已经默认定义和初始化了常用的Converter,他们分别如下: 这里仅仅是定义了Converter并且简单的放在元素之内,任何的元素内容都有两个必须定义的属性.一个是对converter定义的引用和converter能够转换的类. 例如最简单的converter是null converter,它作用是把null和void值转换成javascript的null和undefined值.它是所有converter最简单的,就象调用java的静态方法一样,所以并不需要创建对象. 默认的时候DWR将java void值转换成javascript的null值就是这样设置. 有时java.lang.Void也需要进行这样的转换,所以设置也是相似的.从java传递null值到javascript是没有任何危险性的,所以DWR将这个作为默认的converter,所以你自己不用再把这个converter添加到配置文件的部分去. 基本类型的converter转换int,boolean,double等.当然还包括对应的对象形式Integerv,Boolean等等.DWR在allow预定义了16个配置项目分别用于所有基本类型的转换.就象这样. String类型和Date同样预先定义了Converter,这些converter都没有办法进行改变的,所有的String,Date和数值类型都统一采用默认的converter. 2.1 Array Converters Array的配置项目没有上面介绍的那么直观,默认情况下DWR装载所有的基本类型和可装载的对象,这些包括String,Date等先前介绍的类型.java高级程序员可能会理解为什么match的这行有点奇怪. *符号在上面没有提到,其实这是个可以表示任何字符的通配符号.这些数组可装载的的类型和其他可装载的类型是一样的. 2.2 Bean Converters 一种不能采用默认方式定义的converter就是Bean Converter,这个是将POJO对象转换成javascript相关的数组,反向也一样.基于安全因素的考虑这种类型的converter不能采用默认的方式实现. 假设有个bean并且通过语句设置成远程可用,有种类型的参数他本身是一个带有setter的java bean,但setter会产生严重的隐患.攻击者可能促使这隐患的发生.通过下面的语句就可以设置但个类的bean converter 要想允许转换指定包或子包下所有类的转换可以按照下面的设置 很明显,可以采用下面的方式来转换所有的java bean 2.3 Restricting Property Conversion(指定属性转换) 将象用exclude和incluce来通知DWR隔离creator的方法一样,converter也有一个类似的配置方法.因为指定属性转换只有针对bean才有效(基本类型的转换没有必要指定属性),这个功能只能应用与特定的converter即BeanConverter和从次类派生的所有类.相关配置语法如下 这样就可以限定DWR不能调用Fred对象的getProperty1()和getProperty2()方法,通常这被成为拒绝访问方式,当然你也可以采用下面的方式配置可以访问的方法(授权访问方式) 较好的安全控制大部分都是采用授权访问方式. 2.4 Collection Converters DWR最后两个默认的converter是Maps和Collections 通常converter是采用递归方法转换集合的所有对象. 这里有两个地方需要注意: 仅仅通过反射方法没有办法知道集合元素的类型,所以上面的两个converter能将任何集合转换成相对javascript而言有意义的对象.然而没有办法将不同的集合类类型分别采用不同的转换方法.因为没有办法完全自动进行转换,我们可以应用dwr.xml文件的special signatures syntax配置部分设置类型的转换处理过程. 2.5 DOM Objects DWR 自动将DOM、DOM4J、JDOM和XOM转换成DOM树,前面这几种类型都仅仅返回Document,Element,Node.DWR会自动将这些转换成浏览器DOM对象.通常在启动JDOM Converter时会有一个提示信息,除非你想采用JDOMconverter否则可以忽略. INFO: Missing classdef for converter 'jdom'. Failed to load uk.ltd.getahead.dwr.convert.JDOMConverter. Cause: org/jdom/Document 因为DWR没有办法知道你是否采用jdom converter,所以提示信息是info级别.如果你想采用jdom converter,你必须很清楚地知道jdom converter是否可以被加载.这就是DWR保留上面的提示信息的原因. 3 The Creators DWR共有三种Creator,最简单的”new”是调用bean的默认构造函数创建实例.”scripted”允许采用其他脚本语言创建实例.如BeanShell.在远程bean的默认构造函数不能进行进一步配置的情况下这种类型的creator比较有用.”Spring”类型允许你通过spring创建实例. 下面是关于creator的参考资料和配置参数说明. Creator Parameter User new class 类的全名称(包括包路径) scripted language BSF框架支持的脚本语言名称(BSF为apache项目) scripted script 返回远程对象的脚本,脚本可以指定一些属性,多数情况下一般只设置param节点配置.属性很少设置. spring Location* 任何以location开头的参数,每个参数都是指定一个spring的配置文件,在参数没有设置的情况下DWR会去读取spring的全局的配置文件. spring beanName 从配置文件读取的bean的名称 “scope参数允许你配置creator的生命周期,共有以下几个选项:application,session,request,page.这些参数对于用过jsp或servlet的开发人员并不陌生. 3.1 Uing static methods 如果你想远程调用一个creator的静态方法,并且creator是new类型.因为调用远程bean的方法前DWR不会检测将要执行的方法是不是静态方法,如果是静态方法那么creator就不用创建.这种机制可以适用任何类型的creator,但new类型的creator是最简单配置的. 3.2 Security Creator可以配置类的成员函数的访问权限.creator有授权访问(指明可以被访问的方法)和拒绝访问(指明不允许访问的方法)两种配置方式. 如果要设置除了setWibble方法之外的所有方法都不可访问可以采用下面的设置. 如果采用j2ee访问角色控制的模式 3.3 The 'spring' Creator 3.4 The 'new' Creator DWR已经默认定义了new creator. DWR已经将这配置到了内置的dwr.xml文件,并不需要进行额外的配置. Creator通过调用类的默认的构造方法创建实例.应用new creator有以下几个优点:  安全性 生命周期比较短的creator可以得到更好的安全性,通过不同的应用情况设置适合的生命周期.  低内存开销 在访问量比较大的情况下,可以不用担心发生内存泄露的情况. 配置一个creator的创建和远程方法调用设置: ... 上面的配置信息表示将java.util.date提供给客户端调用,并且引用名称是Blash.当你在客户端调用Blash.toString(reply)时,后台将采用java.util.date的默认构造方法创建一个实例.然后调用实例的tostring方法.客户端的javascript将返回给reply对象(此时reply是java.util.date的字符串形式) 3.5 The 'scripted' Creator DWR 已经默认配置了scripted creator配置, 这种类型的creator采用BSF执行脚本语言并返回bean.例如 ... import org.apache.commons.validator.EmailValidator; return EmailValidator.getInstance(); ... 4 Signatures in dwr.xml Signatures部分用于配置Collections装载对象元素的类型.举个例子来说:下面的java代码没有办法对List集合的对象进行转换. public class Check { public void setLotteryResults(List nos) { ... } } Singatures配置允许我们对DWR要操作的对象类型进行配置.对于了解JDK5泛型编程的开发人员来说下面的格式是很容易理解的. <![CDATA[ import java.util.List; import com.example.Check; Check.setLotteryResults(List nos); ]]> DWR有个专门用于解析上面配置语句的解析器,虽然上面的是JDK5才有的特性,因为有解析器的原因这也可以应用与JDK5之前的版本. 解析规则是不可见的,但有两种例外情况. 一种情况是因为DWR1.0的解析器有个Bug,在有些场合会无法处理返回值的类型.所以应该要避免这种情况的发生. 一种情况是因为解析器是一个语法宽松的解析器,他不象编译器一样对语法有非常严格的要求,所有有时可能一些重要的语句没有配置而无法事先发现. <![CDATA[ import java.util.List; Check.setLotteryResults(List); ]]> DWR的将来版本可能会采用符合java官方规范的解析器,这样可以避免许多出错的情况. Signature部分只用于泛型参数到基本类型参数的转换,对于其他的类型DWR采用反射机制或运行时类型来确定.在没有泛型参数的情况下可以不配置Signature. public void method(String p); public void method(String[] p); 下面的就需要配置,因为反射机制无法完成次类功能. public void method(List p); public void method(Map p); 下面可以不用配置,DWR可以自动完成转换. public void method(List p); public void method(Map p); 下面可以不用设置,DWR可以采用运行时转换. public List method(String p); 有一个值得注意的地方是在javascript所有对象的keys都是一个字符串,你也可以把其他对象作为keys.他们在使用之前都会转换成字符串形式.DWR1.x将采用这个特性来转换成String.以后对象的转换将会在服务器端完成. 5 Scripting Introduction DWR生成的javascript代码和java代码很相似并通过dwr.xml配置输出.相比普通java异步调用之下,通过ajax生成远程接口和java 代码的最大挑战是AJAX异步功能. DWR通过引入一个回调函数,当数据从服务返回数据是调用这个函数。有两种推荐的方法使用回调函数。一在参数列表加入回调功能。二增加调用元数据对象调用。 也可以将回调的功能放在参数列表的前头,但是不建议使用这样的用法,因为在处理自动HTTP对象时候会出现问题。这些方法一般会保持向后兼容。 5.1 Simple Callback Functions 假设有个下面的java方法。 public class Remote { public String getData(int index) { ... } } 在javascript就可以以下面的方式引用。 ... function handleGetData(str) { alert(str); } Remote.getData(42, handleGetData); “42”只是一个传给getdata方法的参数。当然你可以采用下面的写法。 Remote.getData(42, function(str) { alert(str); }); 5.2 Call Meta-Data Objects 另一种使用回调功能的方法是指定一个回调功能选项或其他可选项。上面的例子就变成下面的形式。 Remote.getData(42, { callback:function(str) { alert(str); } }); 这个方法具有以下几个优点:可以依照你的编码习惯来编写程序,更重要的是允许你增加额外的调用选项。 5.3 Timeouts and Handling Errors 除了使用回调功能你还可以指定超时时限和错误处理方法。例如: Remote.getData(42, { callback:function(str) { alert(str); }, timout:5000, errorHandler:function(message) { alert("Oops: " + message); } }); 5.4 Finding the callback method 下面有几个实例来说明回调功能各个参数选项的配置,因为javascript是不支持函数重载的。 Remote.method({ timeout:3 }, { errorHandler:somefunc }); 上面的两个参数一个是bean的参数一个是回调元数据对象。但是没有方法去区别这两种参数选项。在抛开特定的浏览器环境,我们假设null==undefined,所以具有以下规则: 一、 如果一个函数的每个调用都是回调函数,那么他就没有调用元数据对象,所有的参数都是普通java参数。 二、 如果一个最后一个参数具有一个回调功能,那么这个参数就是调用元数据对象。其余的就是普通java参数。 三、 如果第一个参数为null,我们就认为没有回调功能。其余的就是普通java参数。此外还要检查最后一个参数是否为null,如果是则会给予提示信息。 四、 如果最后一个参数为null,则没有回调功能。 五、 还有一个不是很好的约定格式,要表示错误信息。 6 Engin.js文件 这个文件是DWR的引擎文件,他承担着把后台自动生成的javascript接口与前台调用之间的衔接责任。所以任何使用DWR的地方都需要这个文件。 每个使用DWR的页面都必须引入这个文件: 6.1 Call Batching 应用批量功能可以一次性调用多个远程bean方法,因为他是将多个调用做为一次请求,这就减少了与服务器的交互。可以减少许多的开销。 一个批量方法调用以DWREngine.beginBatch()开始WREngine.endBatch()结束。当DWREngine.endBatch()被调用时就说明开始调用批量方法,DWR就将这些方法打包在一起作为一次请求发送给服务器。 DWR会确保所有的方法都回被调用,所以使用批量功能是要注意是否提交了批量调用,如果没有提交批量调用那么这些需要调用的方法将永远排在调用队列直到提交批量调用。 注意:批量调用方法会有一些缺点,比如他不能在那些已经帮定在一起的方法调用顺序不能保证同步。 例如所有的调用元数据对象的接管函数,超时设定,错误处理等的调用都是在批量的级别上,而不是在调用的级别上。如果一个批量调用含有两个不同超时时间设定的方法,那么除了最后一个之外的所有其他方法的超时设定都被忽略。 6.2 Call Ordering 因为AJAX是个普通的异步远程方法调用模式,所以远程调用的返回结果的顺序可能和你发送请求的顺序不一致。DWREngine.setOrdered(boolean)方法允许你设置远程调用返回结果的顺序和你发送调用请求的顺序保持一致。DWR是通过一个远程方法调用已经结束后在发送下一个调用请求来实现这个功能的。 一般情况我们并不需要返回结果顺序和发送请求顺序保持一致。DWR默认是不保持一致的。 提示:因为保持上面的顺序会对应用程序的性能和响应时间,如果其的一个消息发生丢失那么浏览器可能会有意想不到以外情况发生。在使用这个功能的时候必须认真考虑是否真的有必要使用。通常比较好的方法是使用异步模式调用。 6.3 Handling Errors and Warnings 对于一些服务器端发生的错误或警告情况DWR都回调用默认的错误和警告方法并且传递一个相关信息,通常这些发生的错误和异常对于用户来说是不可见的。 下面这个方法主要用于以消息框的方式或者在状态栏里显示一个错误或警告的消息。 要改变错误的处理方法可以使用这个方法:DWREngine.setErrorHandler(function), 改变警告的处理方法可以使用这个方法:DWREngine.setWarningHandler(function). 6.4 Remoting Hooks 参考 DWREngine.setPreHook(function) and DWREngine.setPostHook(function). 如果你想在执行远程方法调用之前或之后进行一些处理的话,你可以使用上面的两个方法。上面参数设置的目标方法必须是没有参数的。如果你想限制特定的组件在一次方法调用没有结束之前不允许再次调用,那么使用上面的方法将很有用。 Post 执行Hooks通常是设置pre-hooks,一般用来撤消先前的操作。关于Hooks的例子可以参照;DWRUtil.useLoadingMessage() 函数。 6.5 Remoting Options(远程调用设置) 关于DWR处理远程调用有若干个设置选项,Method和Verbs对于用户来说是透明的,但对于不同的浏览器可能会有影响。通常DWR会选择正确的方法处理,如果想饶过某些浏览器产生的影响这些参数设置将非常有用。 DWREngine.setMethod(newmethod) 设置Method的实际执行方法,但被设置的方法不能确保被调用。只是DWR首先会尝试调用这个方法。newmethod 必须是DWREngine.XMLHttpRequest 或着 DWREngine.IFrame. DWREngine.setVerb(verb) 允许设置iframe 和 XMLHttpRequest提交数据时的方式,必须是POST或者GET,如果浏览器不支持POST形式,DWR会自动切换到GET方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值