开发者

XPath expression to return value based on value of sibling

Here is a sample xml file that I am trying to pull data from:

<rss>
 <channel>
  <item>
   <title>First Title</title>
   <description>description text</description>
   <component>Distribution - Maintain</component>
   <timeoriginalestimate seconds="3600">1 hour</timeoriginalestimate>
   <timespent seconds="1860">31 minutes</timespent>
  </item>
  <item>
   <title>Second Title</title>
   <description>description text</description>
   <component>Reporting - Security</component>
   <timeoriginalestimate seconds="3600">1 hour</timeoriginalestimate>
   <timespent seconds="1860">31 minutes</timespent>
  </item>
  <item>
   <title>third Title</title>
   <description>description text</description>
   <timeoriginalestimate seconds="5400">1 hour, 30 Minutes</timeoriginalestimate>
   <timespent seconds="2700">45 minutes</timespent>
  </item>
  <item>
   <title>Fourth Title</title>
   <description>description text</description>
   <component>Usability</component>
  </item>
  <item>
   <title>Fifth Title</title>
   <description>description text</description>
   <component>Distribution - Maintain</component>
   <timeoriginalestimate seconds="3600">1 hour</timeoriginalestimate>
   <timespent seconds="7200">2 hours</timespent>
  </item>
 </channel>
</rss>

I want to collect the timeoriginalestimate and timespent nodes by component value. I want to store the value of the component into either a map or a hash as the key and then the value to be the total difference of timeoriginalestimate and timespent

K = "Distribution - Maintain" V = 2ho开发者_运维知识库urs-2hours31minutes

Some of the item's will not have a component and some of the component's will not have the time values. In this case I would like to have the time values just added to the running total for an "other" component.

I am writing this in java and I am planning on printing out a report that will show how much time was estimated versus how much time was actually spent by each component. I'm not sure how to go about this.

Any help would be much appreciated. Thanks!

Sample code to count occurrences of a value:

private XPath featureXPath = XPath.newInstance("count(//rss/channel/item/type[text()='New Feature'])");
LinkedHashMap<String, Double> metrics = new LinkedHashMap<String, Double>();
metrics.put("New Features", (Double)featureXPath.selectSingleNode(doc));

I'm just not sure how I can add the time values to an unknown key and only add the time values for that their respective key


You're asking two questions here I think--(1) how to get the strings and numbers from your document with XPath, and (2) how to handle cases with missing data. I'm not clear on what you want to do with (2) missing data. Your example includes an item that has no time information at all, not even a timespent--I don't know how you want to handle that.

The code below handles extraction and math (1). Doing the subtraction in XPath allows me to make 2 XPath calls instead of 3. I use immediate evaluation to keep the XPath expressions close to where I use them--it seems clearer to me. You may wish to pull them out of the loop and compile them using xpath.compile() to avoid recompiling them on every iteration if your profiling shows significant savings.

XPath xpath = XPathFactory.newInstance().newXPath();
// find all <item>s, regardless of missing data
NodeList items = (NodeList)xpath.evaluate("/rss/channel/item",
                                          doc,
                                          XPathConstants.NODESET);
for (int i=0; i<items.getLength(); i++) {
    Node item = items.item(i);
    // this evaluates to true when all three child elements are present
    // adjust to suit your needs
    if ((Boolean)xpath.evaluate
        ("component and timeoriginalestimate and timespent",
         item, XPathConstants.BOOLEAN)) {
        // handle the "normal" case
        String component = (String)xpath.evaluate
            ("component", item, XPathConstants.STRING);
        Double time = (Double)xpath.evaluate
            ("timeoriginalestimate/@seconds - timespent/@seconds",
             item, XPathConstants.NUMBER);
        map.put(component, time);
    } else {
        // handle the "other" case
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜