先放github
项目需求
个人是做结构方面的,在工作中需要通过PRO/E出一些2D的图档,然后通过2D图档导出一个XML文件,再把XML文件导到EXCEL里面,在EXCEL里面设定每个尺寸的严重度以及CPK等,以供生产的实际管管控。但在实际操作中会存在这么一个问题,有些相同的尺寸,工程师会注明nXdimension的方式,其中n表示有n个相同的尺寸。但导到excel里面,这样的尺寸只会存在一个,工程师需要把这些尺寸ctrl + c, ctrl + v并且每个尺寸都有一个name值,在excel里面每个尺寸的name值都不相同,复制之后的尺寸,还得人工去修改每个尺寸的name值。需要写一个小程序来保证导入之后这些重复的尺寸可以自动补上。
现状
1. PRO/E导出XML文件的程序是公司统一的插件,没有任何接口可以去修改。
2. XML导入EXCEL的插件也是公司统一的,并且有设置密码,在EXCEL里面只有一些固定的按钮,不能做其他任何的操作。
既然图纸的信息是通过XML文件来给到EXCEL里面,中间可以把XML文件来修改,来实现自动复制粘贴的动作。
XML文件分析
xml代码如下:
<TolerancedDim>
<TolerancedDimInfos Type="Sim" Name="L11" Nominal="2.41" TolLower="-0.07" TolUpper="0.07" ViewFolio="new_view_2_1" DrawingLocation="D3" Repetition="4" />
<BasicDims />
<References />
<Comments>
<Comment Comment="L11" />
</Comments>
<Modificators />
</TolerancedDim>
通过分析xml文件可以看到,每个尺寸都有一个Repetition的属性值,如果有重复则数字>0。那这下就好办了,通过读取repetition的值,然后通过循环来进行复制。
List list = document.selectNodes("//ProEngData/TolerancedDims/TolerancedDim/TolerancedDimInfos");
for(int i = list.size() - 1; i >=0; i--){
Element element = (Element) list.get(i);
Attribute name = element.attribute("Name");
Attribute rept = element.attribute("Repetition");
int reptInt = Integer.parseInt(rept.getValue());
if(reptInt > 0){
//System.out.println(name.getValue());
//System.out.println(rept.getValue());
Element parent = element.getParent().getParent();
for(int j = reptInt; j > 0; j--){
Element cloneE = (Element) element.getParent().clone();
String newName = name.getValue() + "-" + j;
cloneE.element("TolerancedDimInfos").attribute("Name").setValue(newName);
cloneE.element("TolerancedDimInfos").attribute("Repetition").setValue("0");
parent.elements().add(i + 1, cloneE);
}
parent.elements().remove(i);
}
}
实测发现大部分的尺寸都好了,但对称度这个尺寸并没有复制。查看xml文件,原来对称度在图纸里面一般不会注明nX的方式,而对称度的重复个数会随着它所附着的尺寸上面。
<TolerancedDim>
<TolerancedDimInfos Type="Sym" Name="S10" Tolerance="0.2" ViewFolio="SECTION B-B_1" DrawingLocation="F6" Repetition="0" />
<BasicDims />
<References>
<Reference Reference="C" />
<Reference Reference="A" />
</References>
<Comments>
<Comment Comment="14.55 +-0.1" />
<Comment Comment="S10" />
</Comments>
<Modificators />
</TolerancedDim>
既然xml文件里面没有Repetition的信息,那就去抓它所附着尺寸的Repetition信息。它所附着的尺寸信息可以从comment里面读到。为了避免抓到其实尺寸相同,公差相同尺寸的信息,这里也用drawinglocation来作一个比较,所便得到更精准的信息。代码如下:
private void clearXML(){
List list = document.selectNodes("//ProEngData/TolerancedDims/TolerancedDim/TolerancedDimInfos");
Iterator iter = list.iterator();
while(iter.hasNext()){
Element element =(Element) iter.next();
if(element.attribute("Type").getValue().equals("Sym")){
// System.out.println(element.attribute("Name").getValue());
Element symEle = element.getParent().element("Comments").element("Comment");
String symLength = symEle.attribute("Comment").getValue().split("\\s")[0];
String symView = element.attribute("ViewFolio").getValue();
String symTol = symEle.attribute("Comment").getValue().split("\\s")[1].split("-")[1];
List simList = document.selectNodes("//ProEngData/TolerancedDims/TolerancedDim/TolerancedDimInfos");
Iterator simIter = simList.iterator();
while(simIter.hasNext()){
Element lengEle = (Element) simIter.next();
if(lengEle.attribute("Type").getValue().equals("Sim")){
String length = lengEle.attribute("Nominal").getValue();
String lView = lengEle.attribute("ViewFolio").getValue();
String lTol = lengEle.attribute("TolUpper").getValue();
String rept = lengEle.attribute("Repetition").getValue();
if(symLength.equals(length) && symView.equals(lView) && symTol.equals(lTol)){
element.attribute("Repetition").setValue(rept);
break;
}
}
}
}
}
}
通过以上两步即可以得到想要的xml文件。
再接下来写保存xml文件的方法。
private void saveAs(File inputXML){
try{
File outputXML = new File(newFileName(inputXML));
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter output = new XMLWriter(new FileWriter(outputXML), format);
output.write(document);
output.close();
}catch (IOException e){
e.printStackTrace();
}
}
为了提高效率,同时处理多个xml文件,增加了一个xmlFilelist,把指定路径下的xml文件全部进行操作。
public void createXMLlist(String preFile){
File xmlPath = new File(preFile);
if(!xmlPath.exists()){
try {
xmlPath.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
if(xmlPath.isDirectory()){
for(File file : xmlPath.listFiles()){
String name = file.getName();
Pattern pattern = Pattern.compile("[a-z]{3}\\d{7}\\.xml", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(name);
if(matcher.matches()){
xmlFileList.add(file);
}
}
}else {
System.out.println("You need select a file, not a path");
}
}
把满足指定正则表达式的xml文件放入list里面进行处理。
另外再做一个GUI,先选取xml所在的文件夹,然后进行修改的操作。最后还增加了一个设置默认路径按钮,把路径保存在一个配置文件里面,这样每次默认打开此文件,以免每次到处找自己要想的文件夹。