I have about 1000 .xml files in different sub directories under one root folder.
My root directory contains the below structure:
RootDir\172\00ad8dc-bff\25.0.xml
RootDir
- The root directory for all my .xml files.172
- The sub directory of the "RootDir" directory. There are many such directories (I gave 172 as an example)00ad8dc-bff
- The sub directory under "172" directory. There are many such directories.25.0.xml
- At this level I have my target .xml files in which the search should be performed.
Conditions on the search:
My program should not search if,
- There is a folder with name "processes".
- The file name is "draft.xml".
There may be many files under this folder (00ad8dc-bff), each representing different version of the .xml file. In this case the version of the .xml file is 25 (obviously this would be the last modified file), search only in the latest version of the .xml file (last modified file). (Note: .xml file names indicate the version of the .xml file).
To achieve the above use case I wrote the below program. The below .xml is "25.xml" so my program should return "my_uuid" and "My Name goes here" if I give for example "4458" as the search string.(4458 text is present in the given .xml file).
My .xml file looks like below and my program is provided right below this .xml file.
<?xml version="1.0" encoding="UTF-8"?>
<my_port
xmlns="http://www.mytest.com/test"
xmlns:a="http://www.mytest.com/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" schemaVersion="007.000.001">
<second-node>
<meta>
<uuid>
<![CDATA[my_uuid]]>
</uuid>
<name>
<string-map>
<pair>
<locale lang="en" country="GB" variant="" />
<value>
<![CDATA[My Name goes here]]>
</value>
</pair>
</string-map>
</name>
<desc>
<string-map>
<pair>
<locale lang="en" country="GB" variant="" />
<value>
<![CDATA[My description]]>
</value>
</pair>
</string-map>
</desc>
<version>
<![CDATA[56.0]]>
</version>
<versionStatus>2</versionStatus>
<latestVersion>
<![CDATA[56.0]]>
</latestVersion>
<state id="12"/>
<pr-name>
<string-map>
<pair>
<locale lang="en" country="GB" variant="" />
<value>
<![CDATA[ppname]]>
</value>
</pair>
</string-map>
</pr-name>
<deadline>
<enabled>false</enabled>
<type>0</type>
<units>0</units>
<rex>
<![CDATA[]]>
</rex>
<aex>
<![CDATA[]]>
</aex>
</deadline>
<pm-notification-settings>
<custom-settings>true</custom-settings>
<notify-initiator>
false</notify-initiator>
<notify>false</notify>
<usrsandgrps>
<usr>
<type>4584</type>
<stringId>
<![CDATA[]]>
</stringId>
</usr>
<usr>
<type>4458</type>
<stringId>
<![CDATA[]]>
</stringId>
</usr>
</usrsandgrps>
<recipients-exp/>
</pm-notification-settings>
<cleanup>3</cleanup>
<arch>30</arch>
<delete>0</delete>
<timeZoneId>
<![CDATA[Country]]>
</timeZoneId>
<dummyTZ>true</dummyTZ>
</meta>
<vrprs>
<vrpr name="name1">
<a:value
xmlns="" xsi:type="dummy" />
<para>true</para>
<req>false</req>
<hide>false</hide>
</vrpr>
<vrpr name="name440">
<a:value
xmlns="" xsi:type="dummy" />
<para>false</para>
<req>false</req>
<hide>false</hide>
</vrpr>
<vrpr name="name75">
<a:value
xmlns="" xsi:type="dummy">0
</a:value>
<para>true</para>
<req>true</req>
<hide>false</hide>
</vrpr>
<vrpr name="name66">
<a:value
xmlns="" xsi:type="dummy">0
</a:value>
<expr>
<![CDATA[=0]]>
</expr>
<para>false</para>
<req>false</req>
<hide>false</hide>
</vrpr>
<vrpr name="name44">
<a:value
xmlns="" xsi:type="dummy" />
<para>false</para>
<req>false</req>
<hide>false</hide>
</vrpr>
<vrpr name="name55">
<a:value
xmlns="" xsi:type="dummy" />
<para>true</para>
<req>false</req>
<hide>false</hide>
</vrpr>
<vrpr name="name4">
<a:value
xmlns="" xsi:type="xsd:int">0
</a:value>
<expr>
<![CDATA[=0]]>
</expr>
<para>false</para>
<req>false</req>
<hide>false</hide>
</vrpr>
</vrprs>
<nodes>
<node uuid="mYnodeUUID">
<guiId>0</guiId>
<owner>
<![CDATA[]]>
</owner>
<icon id="50"></icon>
<picon id="0"></picon>
<fname>
<string-map>
<pair>
<value>
<![CDATA[Name of Nd]]>
</value>
</pair>
</string-map>
</fname>
<x>28</x>
<y>280</y>
<display>
<str-map>
<pair>
<locale lang="en" country="GB" variant="" />
<value>
<![CDATA[Name ofdd]]>
</value>
</pair>
</str-map>
</display>
<desc>
<str-map>
<pair>
<value>
<![CDATA[]]>
</value>
</pair>
</str-map>
</desc>
<notify>false</notify>
<ac>
<local-id>core.0</local-id>
<name>
<![CDATA[Name ofdd]]>
</name>
<ni-default-security>
<can-inherit>true</can-inherit>
<does-inherit>true</does-inherit>
<native-role-map></native-role-map>
</inherited-role-map>
</ni-default-security>
<lingering>false</lingering>
<on-create-ignore-if-active>false</on-create-ignore-if-active>
<on-create-delete-previous-active>false</on-create-delete-previous-active>
<on-complete-delete-previous-completed>false</on-complete-delete-previous-completed>
<pre-triggers></pre-triggers>
<post-triggers></post-triggers>
<event-producers></event-producers>
<exception-flow></exception-flow>
<label>
<fontColor>#000000</fontColor>
<fontFamily>Arial, Helvetica, Sans-Serif</fontFamily>
<fontSize>12</fontSize>
<bold>false</bold>
<italics>false</italics>
<underline>false</underline>
</label>
<deadline>
<enabled>false</enabled>
<type>0</type>
<units>0</units>
<rex>
<![CDATA[]]>
</rex>
<aex>
<![CDATA[]]>
</aex>
</deadline>
<allowsBack>false</allowsBack>
<refreshDefaultValues>false</refreshDefaultValues>
<on-complete-keep-form-data>false</on-complete-keep-form-data>
</node>
</nodes>
<annotations></annotations>
<lanes/>
<attachments></attachments>
<notes>
</second-node>
</my_port>
I am using code as below to search through all .xml files, but I am not sure it is the best way:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class PMXmlUtil {
static BufferedReader br = null;
static ArrayList<String> uuids = new ArrayList<String>();
//The below is the text that I am searching for
static String searchQuery = "4458";
public static String rootDirectory = null;
public static void main(String[] args) {
rootDirectory = getSearchLocation();
int totalXMLFiles = 0;
if (rootDirectory != null && rootDirectory.length() > 0) {
File f = new File(rootDirectory);
try {
if (f.isDirectory()) {
File[] subDir = f.listFiles();
for (File fi : subDir) {
File[] xmlRootDirs = fi.listFiles();
for (File file : xmlRootDirs) {
if (file.isDirectory()) {
File xmlFiles[] = file.listFiles();
File lastModifiedFile = xmlFiles[0];
for (int i = 1; i < xmlFiles.length; i++) {
if (lastModifiedFile.lastModified() < xmlFiles[i].lastModified()) {
lastModifiedFile = xmlFiles[i];
}
}
try {
if (!lastModifiedFile.getName().contains("processes")) {
if (!lastModifiedFile.getName().contains("draft")) {
br = new BufferedReader(new FileReader(lastModifiedFile));
search();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
totalXMLFiles++;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(uuids);
}
private static String getSearchLocation() {
return "C:\\myname\\Desktop\\myRootFolder";
}
private static void search() throws IOException {
boolean uuidLineRead = false;
String tempUUIDLine = null;
String currentLine;
while ((currentLine = br.readLine()) != null) {
String tempTargetTextLine = null;
if (currentLine.contains("uuid") && !uuidLineRead) {
tempUUIDLine = currentLine;
uuidLineRead = true;
}
if (currentLine.contains(searchQuery)) {
tempTargetTextLine = currentLine;
uuids.add(tempUUIDLine);
break;
}
}
}
}
Document
before searching through that, or is this really more of a text-based search? If it is the latter, I will suggest removing thexml
tag. If it is the former, then I actually think this will be a more interesting question. \$\endgroup\$