2

I want to extract every Area between <xsd:headerName> and </xsd:headerName>. Since I write a code generator I can't define how often it is present because it can be different with every xml.

I just get null pointers when executing so what do I do wrong?

Without the list I get the first area but I need all of them separately.

     String xmlToString = null;
     List<String> ComplexTypeList = null;
     String path = "/path/of/xml";
            try {
                xmlToString = FileUtils.readFileToString(new File(path), StandardCharsets.UTF_8);

            } catch (IOException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < headerName.size(); i++) {

                String result = xmlToString.substring(xmlToString.indexOf("<xsd:headerName"), xmlToString.indexOf("</xsd:headerName>") + 18); // +18 so i get </xsd:headerName>
                ComplexTypeList.add(result); // here i get a Nullpointer
            }

EDIT: So now that it almost works I still have the problem that he always takes the same / first area. How can I solve this so that he always jumps to the next one?

halfer
  • 19,824
  • 17
  • 99
  • 186
Trinity
  • 69
  • 5
  • 1
    As for your edit: there's a variant of `indexOf()` that takes a starting index, i.e. just feed it the last index of the closing element (something like `xmlToString.indexOf(" – Thomas Oct 17 '19 at 06:15

3 Answers3

2

You can use a regex instead of manually searching the String:

String str = "<xsd:headerName>  Hello</xsd:headerName><xsd:headerName>World</xsd:headerName><xsd:headerName> and </xsd:headerName>";
Matcher matcher = Pattern.compile("<xsd:headerName>[\\s\\S]*?</xsd:headerName>").matcher(str); // regex pattern

Before Java 9:

List<String> result = new ArrayList<>();
while(matcher.find()) {
    result.add(matcher.group());
}

After Java 9:

List<String> result = matcher.results().map(MatchResult::group).collect(Collectors.toList());

Printing the result:

result.forEach(System.out::println);

Output:

<xsd:headerName>  Hello</xsd:headerName>
<xsd:headerName>World</xsd:headerName>
<xsd:headerName> and </xsd:headerName>
Mushif Ali Nawaz
  • 3,707
  • 3
  • 18
  • 31
1

You really don't want to be processing XML using string manipulation. You need a proper XML parser to turn into some data structure that you can then program against. Basically, if you do it by string handling then your code will inevitably fail against some legal inputs. That might not matter for a one-off ad-hoc process, but you specifically say that things "can be different with every xml", so you clearly need something more robust.

My preferred approach is always to use an XML-specific language (XPath, XSLT, XQuery), but if you want to use Java, then parse the XML into a tree structure (I'd recommend JDOM2 or XOM, but many people continue to use the old-and-clunky DOM that comes with the JDK), and then navigate this tree structure.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
0

Try to declare List as a:

List<String> ComplexTypeList = new ArrayList<String>();
halfer
  • 19,824
  • 17
  • 99
  • 186
KuldeeP ChoudharY
  • 446
  • 1
  • 6
  • 22
  • Oh crap, of course that was dumb as hell. Wow seriously I doubt myself for actually being able to do something like this. Thx for helping – Trinity Oct 17 '19 at 06:04
  • 2
    @SamanChandana: I have reverted your edit to this question, in which you appeared to have proposed a voting fraud arrangement with Kuldeep. Please do not try that here - moderators have access to tools to help detect voting irregularities. – halfer Oct 20 '19 at 20:12
  • @Kuldeep: it appears [you approved that edit](https://stackoverflow.com/review/suggested-edits/24334458). Please only approve edits that add value to posts. – halfer Oct 20 '19 at 20:15