Подскажите можно сделать это через XPath
От: .alex Ниоткуда  
Дата: 19.02.20 17:03
Оценка:
Добрый день. Есть подобный xml:
<?xml version="1.0" encoding="windows-1251"?>
<head>
    <date>22.07.2019</date>
</head>

<rec num="1">
    <main_info>
        <aux>
            <inn>
                <inn_no>132465</inn_no>
            </inn>
        </aux>
    </main_info>

    <data1>
        <id>1111</id>
    </data1>
</rec>

<rec num="2">
    <main_info>
        <aux>
            <inn>
                <inn_no>2222222</inn_no>
            </inn>            
        </aux>
    </main_info>
    
    <data1>
        <id>987</id>
    </data1>
</rec>

<rec num="3">
    <main_info>
        <aux>
            <inn>
                <inn_no>132465</inn_no>
            </inn>
        </aux>
    </main_info>

    <data1>
        <id>8888</id>
    </data1>

    
    <data2>
        <tag2>
            <id>777</id>
        </tag2>
    </data1>
</rec>

Можно ли через XPath из него вытащить следующее:
132465    1111    (пусто)
2222222    987    (пусто)
132465 8888    777
Re: Подскажите можно сделать это через XPath
От: vsb Казахстан  
Дата: 19.02.20 17:30
Оценка:
Здравствуйте, .alex, Вы писали:

A>Добрый день. Есть подобный xml:


Это не валидный XML, у XML должен быть один элемент верхнего уровня (а ещё элемент data2 закрыт тегом data1).

A>Можно ли через XPath из него вытащить следующее:


Можно. Если считать, что элемент верхнего уровня называется root, то выражение /root/rec вытащит элементы rec, вы делаете цикл по ним, выражения main_info/aux/inn/inn_no , data1/id , data2/tag2/id вычисленные относительно элемента rec вытащат соответствующие строки.

Пример кода на Java, который это делает:

        String xml = "" +
                "<?xml version=\"1.0\"?>\n" +
                "<root>\n" +
                "    <head>\n" +
                "        <date>22.07.2019</date>\n" +
                "    </head>\n" +
                "\n" +
                "    <rec num=\"1\">\n" +
                "        <main_info>\n" +
                "            <aux>\n" +
                "                <inn>\n" +
                "                    <inn_no>132465</inn_no>\n" +
                "                </inn>\n" +
                "            </aux>\n" +
                "        </main_info>\n" +
                "\n" +
                "        <data1>\n" +
                "            <id>1111</id>\n" +
                "        </data1>\n" +
                "    </rec>\n" +
                "\n" +
                "    <rec num=\"2\">\n" +
                "        <main_info>\n" +
                "            <aux>\n" +
                "                <inn>\n" +
                "                    <inn_no>2222222</inn_no>\n" +
                "                </inn>\n" +
                "            </aux>\n" +
                "        </main_info>\n" +
                "\n" +
                "        <data1>\n" +
                "            <id>987</id>\n" +
                "        </data1>\n" +
                "    </rec>\n" +
                "\n" +
                "    <rec num=\"3\">\n" +
                "        <main_info>\n" +
                "            <aux>\n" +
                "                <inn>\n" +
                "                    <inn_no>132465</inn_no>\n" +
                "                </inn>\n" +
                "            </aux>\n" +
                "        </main_info>\n" +
                "\n" +
                "        <data1>\n" +
                "            <id>8888</id>\n" +
                "        </data1>\n" +
                "\n" +
                "\n" +
                "        <data2>\n" +
                "            <tag2>\n" +
                "                <id>777</id>\n" +
                "            </tag2>\n" +
                "        </data2>\n" +
                "    </rec>\n" +
                "</root>";
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse(new InputSource(new StringReader(xml)));
        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xPath = xPathFactory.newXPath();
        NodeList recNodes = (NodeList) xPath.evaluate("/root/rec", document, XPathConstants.NODESET);
        for (int i = 0; i < recNodes.getLength(); i++) {
            Node rec = recNodes.item(i);
            System.out.print(xPath.evaluate("main_info/aux/inn/inn_no", rec));
            System.out.print(" ");
            System.out.print(xPath.evaluate("data1/id", rec));
            System.out.print(" ");
            System.out.print(xPath.evaluate("data2/tag2/id", rec));
            System.out.println();
        }
Re[2]: Подскажите можно сделать это через XPath
От: .alex Ниоткуда  
Дата: 20.02.20 13:13
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, .alex, Вы писали:


A>>Добрый день. Есть подобный xml:


vsb>Это не валидный XML, у XML должен быть один элемент верхнего уровня (а ещё элемент data2 закрыт тегом data1).


A>>Можно ли через XPath из него вытащить следующее:


vsb>Можно. Если считать, что элемент верхнего уровня называется root, то выражение /root/rec вытащит элементы rec, вы делаете цикл по ним, выражения main_info/aux/inn/inn_no , data1/id , data2/tag2/id вычисленные относительно элемента rec вытащат соответствующие строки.


Да, xml сам руками набивал, ошибся... Спасибо за ответ, собственно говоря я и хотел узнать можно ли делать XPath запрос, не только относительно документа, а относительно какой-нибудь произвольной ноды, получается можно). Надо бы почитать мануал)
Сделал вот так на PowerShell, вроде работает, но может где-то есть ошибка?...
$doc = [xml]@'
<root> 
    <head> 
        <date>22.07.2019</date> 
    </head>  
    <rec num="1"> 
        <main_info> 
            <aux> 
                <inn> 
                    <inn_no>132465</inn_no> 
                </inn> 
            </aux> 
        </main_info>
        <data1> 
            <id>1111</id> 
        </data1> 
    </rec> 
    <rec num="2"> 
        <main_info> 
            <aux> 
                <inn> 
                    <inn_no>2222222</inn_no> 
                </inn> 
            </aux> 
        </main_info>
        <data1> 
            <id>987</id> 
        </data1> 
    </rec> 
    <rec num="3"> 
        <main_info> 
            <aux> 
                <inn> 
                    <inn_no>132465</inn_no> 
                </inn> 
            </aux> 
        </main_info> 
        <data1> 
            <id>8888</id> 
        </data1>
        <data2> 
            <tag2> 
                <id>777</id> 
            </tag2> 
        </data2> 
    </rec> 
</root>
'@

$rec_nodes = $doc.SelectNodes("root/rec")
ForEach ($rec in $rec_nodes)
{
    echo $rec

    $inn_nodes = $rec.SelectNodes("main_info/aux/inn/inn_no")
    ForEach ($inn in $inn_nodes)
    {
        echo ("`t" + $inn.InnerText)
    }

    $id_nodes = $rec.SelectNodes("data1/id")
    ForEach ($id in $id_nodes)
    {
        echo ("`t" + $id.InnerText)
    }

    $id2_nodes = $rec.SelectNodes("data2/tag2/id")
    ForEach ($id2 in $id2_nodes)
    {
        echo ("`t" + $id2_nodes.InnerText)
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.