2

I am currently working with a XML string (all xml data stored in String xml) that is made of multiple XML files in this format:

<?xml version...>
<File xml:space="preserve">
     <Subfile keyword="Store" tag="0">
          <Value number="1">Amazon</Value>
     </Subfile>
     <Subfile keyword="Owner" tag="1">
          <Value number="1">Alice Murphy</Value>
     </Subfile>
     <Subfile keyword="Date" tag="2">
          <Value number="1">20161114</Value>
     </Subfile>
</File>

<?xml version...>
<File xml:space="preserve">
     <Subfile keyword="Store" tag="0">
          <Value number="1">Walmart</Value>
     </Subfile>
     <Subfile keyword="Owner" tag="1">
          <Value number="1">Eliza Calvin</Value>
     </Subfile>
     <Subfile keyword="Date" tag="2">
          <Value number="1">20161130</Value>
     </Subfile>
</File>
...

I want to retrieve all of the values of "Owner" from xml, but my code apparently only works when there is one xml file. Below is my working code when there is only one xml file within the xml string:

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
    XPath xpath = XPathFactory.newInstance().newXPath();
    String expression = "/File/Subfile[@keyword='Owner']/Value";
    String owner = xpath.compile(expression).evaluate(document);

How do I modify my code to make sure that even in situations where the xml string has more than one xml files, I can still retrieve all the "Owner" values and store them in something like String owner[]?

Thanks a lot for your help!

5
  • I don't know how to deal with this in java, but what about adding a tag that encapsulates all? so add a tag to the beginning of the file like <globaltag> and to the end like </globaltag> Commented Dec 28, 2016 at 18:09
  • @eLRuLL For some reason, this trick works in ruby but not in java. Weird huh? Commented Dec 28, 2016 at 18:55
  • maybe there is another xml parser in java? sorry I can't be of more help. The current xmlparser looks to be searching for the first <?xml and its ending tag Commented Dec 28, 2016 at 18:59
  • @eLRuLL Thanks for your suggestion. I think splitting the string into multiple might be the safest bet here. Commented Dec 28, 2016 at 19:01
  • I assume you un-accepted my answer for a reason. Mind sharing that? Typically, when people un-accept, they received more helpful input; but I don't see that here ... Commented Jun 6, 2017 at 6:56

2 Answers 2

2

Your example shows that each of the XML entries starts with

<?xml version...>

So the easiest approach would be to use String.split() using that pattern; resulting in an array of strings that should actually contain your different file contents.

Alternatively, you could simply use String.index() in order to find the "start index" for each of those <?...> tags; and use substring to retrieve everything up to the next "start index".

Sign up to request clarification or add additional context in comments.

Comments

0

In XPath 3.0/3.1 (as supported in Saxon 9.7 all editions) you could do it in pure XPath by using replace to replace the XML declarations and then parse-xml-fragment to parse the fragment:

parse-xml-fragment(replace('<?xml version...>
<File xml:space="preserve">
<Subfile keyword="Store" tag="0">
<Value number="1">Amazon</Value>
</Subfile>
<Subfile keyword="Owner" tag="1">
<Value number="1">Alice Murphy</Value>
</Subfile>
<Subfile keyword="Date" tag="2">
<Value number="1">20161114</Value>
</Subfile>
</File>

<?xml version...>
<File xml:space="preserve">
<Subfile keyword="Store" tag="0">
<Value number="1">Walmart</Value>
</Subfile>
<Subfile keyword="Owner" tag="1">
<Value number="1">Eliza Calvin</Value>
</Subfile>
<Subfile keyword="Date" tag="2">
<Value number="1">20161130</Value>
</Subfile>
</File>', '<\?xml[^>]*>', ''))/File/Subfile[@keyword='Owner']/Value

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.