VTD官方文档:https://vtd-xml.sourceforge.io/javadoc/
VTD官方例子:https://vtd-xml.sourceforge.io/codeSample/cs1.html
* VTD-XML支持哪些编码类型?
从版本2.6开始,VTD-XML支持ASCII,UTF-8,UTF-8859-1至UTF-8859-16,WIN1250至WIN1258,UTF-16LE和UTF-16BE。
1.全部遍历。
此代码仅仅为遍历打印使用。
@Test
public void vtdXmlTest()
{
long currentTime = System.currentTimeMillis();
long time1 = 0L;
try
{
String filePath = "E:\\a\\201811141230.xml";
//编码转换,因为VTD不支持GBK
convertFile.convertFile(filePath, "GBK", "UTF-8");
time1 = System.currentTimeMillis() - currentTime;
VTDGen vg = new VTDGen();
boolean flag = vg.parseFile(filePath, true);
VTDNav vn = vg.getNav();
foreach3(vn);
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("转换编码用时===========:" + time1);
System.out.println("共用时===========:" + (System.currentTimeMillis() - currentTime));
}
private static void foreach3(VTDNav vn)
throws NavException
{
printVN(vn, "");
if (vn.toElement(VTDNav.FIRST_CHILD))
{
foreach3(vn);
}
else
{
printVNTxt(vn);
}
while (vn.toElement(VTDNav.NEXT_SIBLING))
{
//foreach3(vn);
printVN(vn, "");
if (vn.toElement(VTDNav.FIRST_CHILD))
{
foreach3(vn);
}
else
{
printVNTxt(vn);
}
}
vn.toElement(VTDNav.PARENT);
return;
}
private static void foreach1(VTDNav vn)
throws NavException
{
//指向根节点
vn.toElement(VTDNav.ROOT);
printVN(vn, "+");
//指向一级节点
if (vn.toElement(VTDNav.FIRST_CHILD))
{
printVN(vn, "+++");
//指向二级节点
findSec(vn);
while (vn.toElement(VTDNav.NEXT_SIBLING))
{
printVN(vn, "+++");
//指向二级节点
findSec(vn);
}
}
}
private static void findSec(VTDNav vn)
throws NavException
{
if (vn.toElement(VTDNav.FIRST_CHILD))
{
//存在二级节点并打印
printVN(vn, "+++++");
printVNTxt(vn);
//打印所有的二级节点
while (vn.toElement(VTDNav.NEXT_SIBLING))
{
printVN(vn, "+++++");
printVNTxt(vn);
}
vn.toElement(VTDNav.PARENT);
}
else
{
printVNTxt(vn);
}
}
private static void printVN(VTDNav vn, String pre)
throws NavException
{
System.out.println("\n" + pre + "节点名:" + vn.toString(vn.getCurrentIndex()));
findAttr(vn);
}
private static void printVNTxt(VTDNav vn)
throws NavException
{
int t = vn.getText();
if (t != -1)
{
System.out.print(" 节点值:" + vn.toString(t));
}
}
private static void findAttr(VTDNav vn)
throws NavException
{
AutoPilot ap = new AutoPilot(vn);
ap.selectAttr("*");
int attrCount = vn.getAttrCount();
for (int i = 0; i < attrCount; i++)
{
int a = ap.iterateAttr();
if (a != -1)
{
String attrName = vn.toString(a);
int attrValueIndex = vn.getAttrVal(attrName);
if (attrValueIndex != -1)
{
String attrValue = vn.toString(attrValueIndex);
System.out.print(" 节点属性值:" + attrName + " : " + attrValue + ";");
}
}
}
return;
}
也感谢上述大佬给的思路。!!!致谢
2.在导出的过程中对标签,属性以及值的操作,因为xml标签的不同,所以各位在查看我的代码的时候,注意查看一下标签,根据自己的标签名字进行修改。
public static Boolean CheckCrc(String local_path){
try {
VTDGen gen = new VTDGen();
// 解析student.xml对象,不含有命名空间
gen.parseFile(local_path, false);
VTDNav vn = gen.getNav();
XMLModifier xmlModifier=new XMLModifier(vn);
foreach3(vn,xmlModifier);
VTDNav vtdNav = xmlModifier.outputAndReparse();
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(new String(vtdNav.getXML().getBytes()));
System.out.println(m.replaceAll(""));
String fileCRC32 = FileToCRCUtil.getStringCRC32(m.replaceAll("").replaceAll(CRCFILE_SPACE," "));
isDelete=false;
return CRC.equals(fileCRC32);
}catch (Exception e){
e.printStackTrace();
return false;
}
}
private static void foreach3(VTDNav nav, XMLModifier xmlModifier) throws NavException, ModifyException, UnsupportedEncodingException {
findAttr(nav,xmlModifier);
if (nav.toElement(VTDNav.FIRST_CHILD)){
foreach3(nav,xmlModifier);
}else{
printVNTxt(nav,xmlModifier);
}
while(nav.toElement(VTDNav.NEXT_SIBLING)){
findAttr(nav, xmlModifier);
if (nav.toElement(VTDNav.FIRST_CHILD)){
foreach3(nav,xmlModifier);
}else{
printVNTxt(nav,xmlModifier);
}
}
nav.toElement(VTDNav.PARENT);
}
private static void printVNTxt(VTDNav vn,XMLModifier xmlModifier) throws NavException, ModifyException, UnsupportedEncodingException {
int t = vn.getText();
if (t != -1){
if(vn.toString(t).contains(" ")){
String value =vn.toString(t).replaceAll(" ",CRCFILE_SPACE);
xmlModifier.updateToken(t,value);
}
}
}
private static void findAttr(VTDNav vn, XMLModifier xmlModifier) throws NavException, ModifyException {
AutoPilot ap = new AutoPilot(vn);
ap.selectAttr("*");
if("IED".equals(vn.toString(vn.getCurrentIndex()))){
int attrCount = vn.getAttrCount();
for (int i = 0; i < attrCount; i++){
int a = ap.iterateAttr();
if (a != -1){
String attrName = vn.toString(a);
if(!"name".equals(attrName)){
xmlModifier.removeAttribute(a);
}
}
}
}else if("FCDA".equals(vn.toString(vn.getCurrentIndex()))){
int attrCount =vn.getAttrCount();
if(!isDelete){
for (int i = 0; i < attrCount; i++){
int a = ap.iterateAttr();
if (a != -1){
String attrName = vn.toString(a);
if("desc".equals(attrName)){
xmlModifier.removeAttribute(a);
}
}
}
}else {
for (int i = 0; i < attrCount; i++){
int a = ap.iterateAttr();
if (a != -1){
String attrName = vn.toString(a);
if(!"bType".equals(attrName)){
xmlModifier.removeAttribute(a);
}
}
}
}
}else if("CRC".equals(vn.toString(vn.getCurrentIndex()))){
int attrCount=vn.getAttrCount();
for(int i = 0; i < attrCount; i++){
int a =ap.iterateAttr();
if(a != -1){
String attrName=vn.toString(a);
if("id".equals(attrName)){
CRC=vn.toString(vn.getAttrVal(attrName));
}
}
}
xmlModifier.remove();
}else if ("GOOSESUB".equals(vn.toString(vn.getCurrentIndex()))){
isDelete=true;
}else {
int attrCount =vn.getAttrCount();
for (int i = 0; i < attrCount; i++){
int a = ap.iterateAttr();
if (a != -1){
String attrName = vn.toString(a);
if("desc".equals(attrName)){
xmlModifier.removeAttribute(a);
}
}
}
}
}
}
以上代码,是我在原有基础之上修改,对标签以及属性进行操作,并且全文去除空格,换行符,但是最后值内部的属性是没有去除的。这个是我需求的逻辑,如有需要可以进行参考,也可以一起沟通交流,共同学习。