[JAVA]怎样验证XML文件是否符合schema定义

两种方法:

1。 使用SAX解析:

/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void saxValidation(String xmlPath, String schemaPath){
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setValidating(true);
SAXParser saxParser = saxParserFactory.newSAXParser();
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaPath);
DefaultHandler handler = new DefaultHandler();
saxParser.parse(xmlPath, handler);
} catch(SAXException exc) {
exc.printStackTrace();
}
}

2。 使用DOM解析:

/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void domValidation(String xmlPath, String schemaPath){
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
docBuilderFactory.setValidating(true);
docBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
docBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaPath);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xmlPath);
} catch(DOMException exc) {
exc.printStackTrace();
}
}

使用JAVA将彩色图片变为1bit黑白图片

最近做的project需要涉及到对扫描图片的文字识别,需要将扫描得到的彩色图片变为1bit的黑白图片。

搜索到很多解决方案,基本的归纳为两个步骤,首先要将彩色图片变为8bit灰度图片(grayscale image),然后再进一步变为1bit的单色图片(1bit monochrome)。

使用ColorConvert和Dithering操作

代码

目前JAVA最新的图片处理包应该是JAI(Java Advanced Imaging),在JAI API的FAQ页面上,找到了下面的方法来完成这两步工作:

将彩色图片转换为8bit灰度图片(使用ColorConvert颜色转换操作)
public RenderedImage convertTo8BitGray(RenderedImage colorImage){
ParameterBlock pb = new ParameterBlock();
pb.addSource(colorImage);
ColorModel cm = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY),
new int[]{8},
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
pb.add(cm);
RenderedImage grayImage = JAI.create("ColorConvert", pb);
return grayImage;
}
将8bit灰度图片转换为1bit黑白图片 (使用errordiffusion或ordereddither操作)
public  RenderedImage applyDithering(RenderedImage grayImage, boolean isErrorDiffusion){
// Load the ParameterBlock for the dithering operation
// and set the operation name.
ParameterBlock pb = new ParameterBlock();
pb.addSource(grayImage);
String opName = null;
if(isErrorDiffusion) {
opName = "errordiffusion";
LookupTableJAI lut = new LookupTableJAI(new byte[] {(byte)0x00, (byte)0xff});
pb.add(lut);
pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
} else {
opName = "ordereddither";
ColorCube cube = ColorCube.createColorCube(DataBuffer.TYPE_BYTE,
0, new int[] {2}); //尝试改变2为其它值,可以得到不同效果
pb.add(cube);
pb.add(KernelJAI.DITHER_MASK_441);
}
// Create a layout containing an IndexColorModel which maps
// zero to zero and unity to 255.
ImageLayout layout = new ImageLayout();
byte[] map = new byte[] {(byte)0x00, (byte)0xff};
ColorModel cm = new IndexColorModel(1, 2, map, map, map);
layout.setColorModel(cm);
// Create a hint containing the layout.
RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
// Dither the image.
bwImage = JAI.create(opName, pb, hints);
return bwImage;
}

问题

这段sample code在很多地方都被提到过,我不知道别人是否能够让它顺利执行,但是在我的机器上是不行的。

问题主要出在第一个convertTo8BitGray()函数里的ColorConvert操作上。在执行完ColorConvert之后,图片的ColorModel的numberOfComponents变为1。我的理解是因为变为灰度图片,只有一个色了。

然而不知为什么,图片的SampleModel的numberOfBands却仍然保持了3,这就造成了SampleModel和ColorModel 不兼容,所以程序总是抛出java.lang.IllegalArgumentException: The specified ColorModel is incompatible with the image SampleModel…的错误。

More… »

ABAP中如何检查字母数字类型(alpha numeric)的变量

Business requirment经常要求某个ID的值只能包含26个字母和10个数字字符,这就要求ABAP程序能够检查相应变量内容,辨别特殊字符。sap-img上的一个例子提供了这样的功能:

REPORT ZCHECK_ALPHA_NUMERIC.

* Declare the variable

* For Length
data: serial_length type i.

* For Alpha numeric
data: str type string.
data: valid_characters type string.

* Fill in those valid characters you need to check
concatenate ‘0123456789′ ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’
‘abcdefghijklmnopqrstuvwxyz’ into valid_characters.

* User Input
parameters testchar(10) default ‘12345abc’.

* Get User Input
str = testchar.

* The Checks
if str co valid_characters.
write: / str, ‘Characters are OK’.
else.
write: / str, ‘Characters are NOT OK’.
endif.

*– End Program

基于同样的原理,下面这个subroutine可以去掉一个字符串中的所有特殊字符

*&———————————————————————*
*&      Form  convert_character_entities
*&———————————————————————*
*  This form removes all non-alpha-numeric characters from a string
*———————————————————————-*
*      <–
*———————————————————————-*

FORM remove_non_alpha_numeric_char.
DATA: l_teststr       TYPE string,
l_alpha_numeric TYPE string.
DATA: l_strlen TYPE i.

DATA: l_char TYPE c.

l_teststr = ‘ref0 0@2$45*8′.
l_strlen = strlen( l_teststr ).
WRITE: / l_teststr, ‘length:’, l_strlen.

l_alpha_numeric = ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’.

WHILE l_strlen <> 0.
l_strlen = l_strlen - 1.
l_char = l_teststr+l_strlen(1).
IF l_alpha_numeric NA l_char.
REPLACE SECTION OFFSET l_strlen LENGTH 1 OF l_teststr WITH ”.
ENDIF.
ENDWHILE.
l_strlen = strlen( l_teststr ).
WRITE: / l_teststr, ‘length:’, l_strlen.

ENDFORM.

SAP中国家代码和国家名称对应查询

SAP中的国家代码表是T005T.

另外 ADRC表的COUNTRY字段的帮助视图(Help View),也可以看到country code 和 country name的对应表。

ABAP字符串比较中空格的影响

ABAP对字符串有很多隐形的操作,有时更方便程序员,有时又比较容易使人困惑。

比如在比较字符串的值时,ABAP会自动忽视有效字符后面的空格,而如果在字符前面有空格,则会影响比较的结果。

比如: ‘X’ 和 ‘X__’ 比较的结果是相等;而’X'和’__X’比较的结果则是不相等。 (这里下划线__代表空格)

运行下面的程序可以看到效果:

DATA: l_string1 TYPE string,
l_string2 TYPE string,
l_string3 TYPE string.
l_string1 = ‘X’. “No space
l_string2 = ‘X ‘. “Space after X
l_string3 = ‘ X’. “Space before X
IF l_string1 EQ l_string2.
WRITE: / ‘String 1 and String 2 are identical.’.
ELSE.
WRITE: / ‘String 1 and String 2 are NOT identical.’.
ENDIF.
IF l_string1 EQ l_string3.
WRITE: / ‘String 1 and String 3 are identical.’.
ELSE.
WRITE: / ‘String 1 and String 3 are NOT identical.’.
ENDIF.

运行结果是输出:

String 1 and String 2 are identical.

String 1 and String 3 are NOT identical.

简单话内表(internal table)

内表是一个运行状态下存在的实例,它在程序开始运行时才生成,在程序结束运行时被销毁。

内表包含两个部分,可有可无的标题行(HeaderLine),和必需的表身。进出内表的值都必须通过标题行。

程序例子:

* 声明
data: begin of itab occurs 0,
x type c,
y type i,
end of itab.

* 初始化标题行 headerline
itab-x = ‘d’.
itab-y = 34.

* 向内表中存入值
appene itab.
appene itab.
appene itab.

* 读取内表中的值
loop at itab .
write: / itab-x, itab-y. “输出列表
endloop.

ABAP内表(internal table)有关的系统变量

SY-TABIX – 内表当前行的索引号。SY-TABIX 的值可以被以下命令修改,但是只适用于索引表(index table)。对于哈希表(Hashed table),这个系统变量的值为空或0。

  1. APPEND 将 SY-TABIX 的值置为表最后一行的索引号,也就是说它将等于内表的行数。
  2. COLLECT 将 SY-TABIX 的值置为现有或刚刚插入的行的索引号。如果内表为哈希(hashed table)表的话,SY-TABIX 被置为0。
  3. LOOP AT 将 SY-TABIX 的值置为每一次循环开始时的当前行索引号,在整个循环的结束时 SY-TABIX 被恢复为它在进入循环之前的值。对于哈希表(hashed table),它的值为0。
  4. READ TABLE 将 SY-TABIX 的值置为被读取的行的索引号。如果使用二分查找(binary search),而没有找到的话,SY-TABIX 将等于所有行数或行数加1。如果是使用顺序查找而没有找到的话,SY-INDEX 没有定义。
  5. SEARCH <itab> FOR 将 SY-TABIX 的值置为找到要查找字符串所在的行的索引号。

SY-TFILL — 在使用命令 DESCRIBE TABLE、LOOP AT、 和 READ TABLE之后,SY-TFILL 的值为相应内表的行数。

SY-TLENG — 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后,SY-TLENG 的值为相应内表的行的长度。

SY-TOCCU – 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后,SY-TLENG 的值为相应内表所占用的内存。

SAP ABAP 性能优化技巧 — 性能分析的工具

以下是SAP提供的各种对ABAP对象进行性能分析的工具:

  1. 运行实时分析 transaction SE30

这个 transaction 可以给出对一个ABAP程序的所有分析,包括数据库和非数据库处理操作。

  1. SQL 追踪 transaction ST05

追踪列表有很多行不是关于 SELECT 语句的,因为任何ABAP程序的执行都会需要很多附加的管理性SQL调用。可以使用过滤器来显示追踪列表的输出来只显示有关的行。

追踪列表同时包含与一个SELECT语句相关的多个不同 SQL 命令,因为 R/3 数据库接口 — R/3应用服务器的一个复杂的组成部分 — 将每一个 Open SQL 命令映射为一个或一系列的物理数据库调用指令并执行这些指令。这种映射依赖于具体的调用和数据库系统,对R/3的性能是非常重要的。例如在我们的测试程序中,SPFLI表上的 SELECT-ENDSELECT 循环被映射成为一连串Oracle环境下的 PREPARE-OPEN-FETCH 的物理调用。

追踪列表中的SQL语句的WHERE条件与ABAP语句中的 WHERE 是不同的。因为在 R/3 系统中,客户是一个具有自己的主记录(master records)和自己的一组数据表的独立单元。使用ABAP,每一个 Open SQL 的命令都会自动在相应的客户环境中运行。因此,如果被查找的表有客户(client)字段的话,每一个WHERE语句都会自动添加一个条件包含实际的客户代码

要查看一个语句的执行计划(execution plan),只需要将光标放在 PREPARE 语句上,然后选择 Explain SQL。具体的执行计划的解释取决于使用的数据库。


返回文章目录

SAP ABAP 性能优化技巧 — 使用 ABAP “Sort” 取代 “Order By”

order by 命令是在数据库服务器上执行的,而 sort 语句是在应用服务器上执行的。因此,与其在select语句中使用order by命令,不如将数据先读取到内表中然后使用sort命令来将结果排序,因为应用服务器上的执行速度要比数据库服务器快。


返回文章目录

SAP ABAP 性能优化技巧 — 正确使用”inner join”

当多个 SAP 表在逻辑上关联的时候,总是建议使用右关联 inner join 来从中读取数据。这会降低网络的负载。

以两个表为例:zairln 和 zflight。表 zairln 有字段 airln 存储了航空公司的代码,和字段 lnnam 存储了航空公司的名称。表 zflight 有航空公司代码字段 airln, 以及其他字段存储了航空公司运行的航班的详细信息。

既然两个表在逻辑上通过 airln 字段可以关联,建议使用以下 inner join:

Select a~airln a~lnnam b~fligh b~cntry into table int_airdet

From zairln as a inner join zflight as b on a~airln = b~airln.

这样就可以根据选择条件来限制数据,以上inner join还可以增加 where 条件来进一步限制选择条件。


返回文章目录