Извлечь значения для более чем одного значения узла атрибута с помощью выражения XPath - PullRequest
0 голосов
/ 23 апреля 2020

Как извлечь значение более чем одного узла атрибута с помощью выражения XPath?

Пример файла XML:

<tag1>
    <tag2>
        <tag3 id="1">
            <tage4>
                <tage4code code="1">
                    <tag5>
                        <tage4Value Day="14" Month="Oct" Year="2000" />
                    </tag5>
                    <tag5>
                        <tage4Value Month="Oct" Year="2001" />
                    </tag5>
                    <tag5>
                        <tage4Value Year="2002" />
                    </tag5>
                    <tag5>
                        <tage4Value Day="1" Month="Jan" Year="1999" />
                    </tag5>
                    <tag5>
                        <tage4Value Year="1940" />
                    </tag5>
                </tage4code>
            </tage4>
        </tag3>
    </tag2>
</tag1>

Пока у меня есть строка XPath:

XPathExpression expr = xpath.compile("concat((/tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value/@Day, '/' , /tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value/@Month, '/', /tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value/@Year)");
                     NodeList combination1 = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
                     for (int a = 0; a <= combination1.getLength(); a++) {
                            System.out.println("date : " + combination.item(a).getNodeValue());
                        }

Мой ожидаемый результат

14 / окт / 2000 окт / 2001 2002 1 / янв / 1999 1940

Может ли кто-нибудь помочь исправить мое XPathExpression

Ответы [ 3 ]

1 голос
/ 24 апреля 2020

Решение XPath 2.0 :

tokenize(replace(replace(replace(substring-after(string-join(//tag5/*|//tag5//@*,","),","),",,","%"),","," ")," ","/"),"%")

Вывод:

String='14/Oct/2000'
String='Oct/2001'
String='2002'
String='1/Jan/1999'
String='1940'

Решение XPath 1.0 :

concat(translate(normalize-space(concat((//tage4Value)[1]/@Day," ",(//tage4Value)[1]/@Month," ",(//tage4Value)[1]/@Year))," ","/"),"|",translate(normalize-space(concat((//tage4Value)[2]/@Day," ",(//tage4Value)[2]/@Month," ",(//tage4Value)[2]/@Year))," ","/"),"|",translate(normalize-space(concat((//tage4Value)[3]/@Day," ",(//tage4Value)[3]/@Month," ",(//tage4Value)[3]/@Year))," ","/"),"|",translate(normalize-space(concat((//tage4Value)[4]/@Day," ",(//tage4Value)[4]/@Month," ",(//tage4Value)[4]/@Year))," ","/"),"|",translate(normalize-space(concat((//tage4Value)[5]/@Day," ",(//tage4Value)[5]/@Month," ",(//tage4Value)[5]/@Year))," ","/"))

Вывод:

String='14/Oct/2000|Oct/2001|2002|1/Jan/1999|1940'

Или с новым разделителем строк:

concat(translate(normalize-space(concat((//tage4Value)[1]/@Day," ",(//tage4Value)[1]/@Month," ",(//tage4Value)[1]/@Year))," ","/"),codepoints-to-string(10),translate(normalize-space(concat((//tage4Value)[2]/@Day," ",(//tage4Value)[2]/@Month," ",(//tage4Value)[2]/@Year))," ","/"),codepoints-to-string(10),translate(normalize-space(concat((//tage4Value)[3]/@Day," ",(//tage4Value)[3]/@Month," ",(//tage4Value)[3]/@Year))," ","/"),codepoints-to-string(10),translate(normalize-space(concat((//tage4Value)[4]/@Day," ",(//tage4Value)[4]/@Month," ",(//tage4Value)[4]/@Year))," ","/"),codepoints-to-string(10),translate(normalize-space(concat((//tage4Value)[5]/@Day," ",(//tage4Value)[5]/@Month," ",(//tage4Value)[5]/@Year))," ","/"))

Вывод:

String='14/Oct/2000
Oct/2001
2002
1/Jan/1999
1940'
0 голосов
/ 24 апреля 2020

Таким образом, мы можем создать динамический c способ чтения ребенка.

xpathExpression = "count(//tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value)";
                double nodeList1 = (double) xpath.compile(xpathExpression).evaluate(doc, XPathConstants.NUMBER);
                int s = (int) (nodeList1);
                for (int z = 1; z <= s; z++) {

                    xpathExpression = "normalize-space(concat((//tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value)["
                            + z
                            + "]/@Day,\" \",(//tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value)["
                            + z
                            + "]/@Month,\" \",(//tag1/tag2/tag3[@id=1]/tage4/tage4code[@code=1]/tag5/tage4Value)["
                            + z + "]/@Year))";
                    String year = (String) xpath.evaluate(xpathExpression, doc, XPathConstants.STRING);
                    System.out.println(year);
                }
0 голосов
/ 24 апреля 2020

Это выражение xpath

//tag3[@id="1"]//tage4code[@code=1]//tag5/tage4Value/concat(@Day,'/',@Month,'/',@Year)

должно вывести

14/Oct/2000
/Oct/2001
//2002
1/Jan/1999
//1940
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...