Извлечение измерений из узлов XML - PullRequest
0 голосов
/ 26 ноября 2018

Я анализирую большие XML-файлы, используя Java 8 и XmlPath 1.0.Я хочу извлечь имя Test , его измеренные значения и результат (Пройдено или Не удалось).Каждый Test может иметь множество TestResult , который содержит один из двух типов ограничений:

  • SingleLimit, который будет иметь только один
  • LimitPair, который всегда будет иметь два предела

    <tr:Test ID = "282" name = "DIP1-8 High">  
        <tr:Extension>
            <ts:TSStepProperties>
                ...
            </ts:TSStepProperties>
        </tr:Extension>
        <tr:Outcome value = "Passed" /> <!-- value -->
        <tr:TestResult ID = "xyz" name = "TC 8.7.4 - Current breaker output J10:1-2"> <!-- name -->
        <tr:TestLimits>
            <tr:Limits>
                <c:LimitPair operator = "AND">
                    <c:Limit comparator = "GE">
                        <!-- value -->
                        <c:Datum nonStandardUnit = "V" value = "2.8" xsi:type="ts:TS_double" flags = "0x0000"/> 
                    </c:Limit>
                    <c:Limit comparator = "LE">
                        <!-- value -->
                        <c:Datum nonStandardUnit = "V" value = "3.5" xsi:type="ts:TS_double" flags = "0x0000"/>
                    </c:Limit>
                </c:LimitPair>
            </tr:Limits>
            </tr:TestLimits>
        </tr:TestResult>
    </tr:Test>
    

В настоящее время я использую эти пути для извлечения измерений PairLimit и для создания строк, содержащих значения.

Мой вопрос заключается в том, как мне написать код / ​​xPaths, чтобы позаботиться о возможном множестве TestResults в одном тесте.

В начале я предположил, что у Test может быть только PairLimit или SingleLimit, что было неправильно.Мой текущий код правильно извлекает все значения, но назначенные измерения неверны, когда в Test есть много TestResults.

Например, если Test ID = 1 содержит 3 (три) TestResults , то в последней строке, содержащей измерения, у меня будут значения из первого теста в течение секунды, потому что он "переопределит"ценности.

        private ArrayList<String> preparePairLimitPaths() {
    final ArrayList<String> list = new ArrayList<>();
    list.add("//Test[TestResult//LimitPair]/@name");
    list.add("//Test/TestResult[TestLimits//LimitPair]/TestData/Datum/@value");
    list.add("//Test/TestResult/TestLimits/Limits/LimitPair/Limit[*]/Datum/@value");
    list.add("//Test/TestResult/TestLimits/Limits/LimitPair/Limit[*]/Datum/@value");
    list.add("//Test[TestResult//TestLimits//LimitPair]/Outcome/@value");
    return list;
}
for (String expr : preparePairLimitPaths) {
    try {
        final NodeList evaluate = (NodeList) xPath.evaluate(expr, parse, XPathConstants.NODESET);
        for (int i = 0; i < evaluate.getLength(); i++) {
            final String textContent = evaluate.item(i).getTextContent();
            if (textContent != null && !textContent.isEmpty()) {
                stringBuilder.append(textContent).append(";");
            }
        }
        stringBuilder.append("@@@");
    } catch (XPathExpressionException e) {
        e.printStackTrace();
    }
}

1 Ответ

0 голосов
/ 26 ноября 2018

Вы можете просто выполнить итерацию для каждого Test , а затем выполнить итерацию для каждого TestResult , а затем поместить логику с TestLimits и т. Д.

    NodeList allTests = (NodeList) xPath.evaluate("/xml/Test", xmlDocument, XPathConstants.NODESET);
    for (int i = 0; i < tests.getLength(); i++) {
        Element singleTest = (Element) tests.item(i);
        // Here, you can extract some values from your test like:
        // testOutcome = xPath.evaluate("Outcome/@value", singleTest);

        NodeList testResults = (NodeList) xPath.evaluate("TestResult",test, XPathConstants.NODESET);

        for (int j=0; j<testResults.getLength(); j++) {
            // Now you can iterate over all your testResults from test
            // testResultName = xPath.evaluate("@name",testResults.item(j)));
        }
    }
...