2010-02-12 3 views
1

Вот пример XML-файл, который я пытаюсь вытащить данные из:выражение XPath для возврата значения на основе значения собрата

<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> 

Я хочу, чтобы собрать timeoriginalestimate и timespent узлов по component значения. Я хочу, чтобы сохранить значение component в любой карте или хэш в качестве ключа и потом значение будет общая разница timeoriginalestimate и timespent

K = «Распределение - Поддерживайте» V = 2hours-2hours31minutes

некоторые из item-й не будет иметь component и некоторые из component-й не будет иметь значение времени. В этом случае я хотел бы, чтобы значения времени, добавляемые только к текущему итогу для «другого» компонента.

Я пишу это в java, и я планирую распечатать отчет, в котором будет показано, сколько времени было оценено в сравнении с тем, сколько времени было потрачено каждым компонентом. Я не уверен, как это сделать.

Любая помощь будет высоко оценена. Благодаря!

Пример код для подсчета вхождений значения:

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)); 

Я просто не знаю, как я могу добавить значение времени в неизвестный ключ и только добавить значение времени для этого их соответствующей клавиши

+0

Любой код с вашей стороны, что вы пробовали? –

+0

Я добавил немного кода, который работал для выполнения другой задачи ..., которая просто скажет мне количество раз, когда тип элемента имеет значение «новая функция». – robbie

ответ

0

Здесь вы задаете два вопроса: (1) как получить строки и числа из вашего документа с помощью XPath и (2) как обрабатывать случаи с отсутствующими данными. Я не понимаю, что вы хотите сделать с (2) отсутствующими данными. Ваш пример включает item, который не имеет никакой информации о времени вообще, даже не timespent - Я не знаю, как вы хотите с этим справиться.

Код ниже обрабатывает извлечение и математику (1). Выполнение вычитания в XPath позволяет мне делать 2 вызова XPath вместо 3. Я использую немедленную оценку, чтобы выражения XPath были близки к тому, где я их использую, - мне кажется яснее. Вы можете вытащить их из цикла и скомпилировать их с помощью xpath.compile(), чтобы избежать перекомпиляции их на каждой итерации, если профилирование показывает значительную экономию.

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 
    } 
} 
Смежные вопросы