@beduin01

Почему xpath не работает на файле?

Не могу понять, почему на тестовом файле xpath находит значение тега, а на реальном возвращает None:

from lxml import etree

parser = etree.XMLParser(ns_clean=True)
tree = etree.parse('real.xml', parser)
#tree = etree.parse('test.xml', parser)

#print(dir(tree.find("//id")))
print(tree.find("//id").text)

test.xml:
<aa>
<dd></dd>
<foo>
<bar>qqq</bar>
<id>123</id>
</foo>
</aa>


Пример реального XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:export xmlns:ns5="http://zakupki.gov.ru/oos/CPtypes/1" xmlns="http://zakupki.gov.ru/oos/types/1" xmlns:ns6="http://zakupki.gov.ru/oos/pprf615types/1" xmlns:ns7="http://zakupki.gov.ru/oos/EPtypes/1" xmlns:ns8="http://zakupki.gov.ru/oos/printform/1" xmlns:ns9="http://zakupki.gov.ru/oos/control99/1" xmlns:ns2="http://zakupki.gov.ru/oos/export/1" xmlns:ns3="http://zakupki.gov.ru/oos/common/1" xmlns:ns4="http://zakupki.gov.ru/oos/base/1">
    <ns2:fcsNotification111 schemeVersion="9.0">
        <id>18934116</id>
        <purchaseNumber>0373100043519000001</purchaseNumber>
        <docPublishDate>2019-01-11T11:06:05.465+03:00</docPublishDate>
        <docNumber>№0373100043519000001</docNumber>
        <href>http://zakupki.gov.ru/epz/order/notice/inm111/view/common-info.html?regNumber=0373100043519000001</href>
        <printForm>
            <url>http://zakupki.gov.ru/epz/order/notice/printForm/viewXml.html?noticeId=18934116</url>
            <signature type="CAdES-BES"></signature>
        </printForm>
        <purchaseObjectInfo>Теплоснабжение</purchaseObjectInfo>
        <purchaseResponsible>
            <responsibleOrg>
                <regNum>03731000435</regNum>
                <consRegistryNum>001Ч1823</consRegistryNum>
                <fullName>ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ УЧРЕЖДЕНИЕ НАУКИ ИНСТИТУТ ВОДНЫХ ПРОБЛЕМ РОССИЙСКОЙ АКАДЕМИИ НАУК</fullName>
                <postAddress>Российская Федерация, 119333, Москва, УЛ ГУБКИНА, 3</postAddress>
                <factAddress>Российская Федерация, 119333, Москва, УЛ ГУБКИНА, 3</factAddress>
                <INN>7701003690</INN>
                <KPP>773601001</KPP>
            </responsibleOrg>
            <responsibleRole>CU</responsibleRole>
        </purchaseResponsible>
        <placingWay>
            <code>EP111</code>
            <name>Закупка у единственного поставщика (подрядчика, исполнителя) с учетом положений ст. 111 Закона № 44-ФЗ</name>
        </placingWay>
        <lots>
            <lot>
                <lotNumber>1</lotNumber>
                <maxPrice>400000</maxPrice>
                <currency>
                    <code>RUB</code>
                    <name>Российский рубль</name>
                </currency>
                <OKPD2>
                    <code>35.30.11.111</code>
                    <name>Энергия тепловая, отпущенная тепловыми электроцентралями (ТЭЦ)</name>
                </OKPD2>
                <OKPD2>
                    <code>35.30.11.111</code>
                    <name>Энергия тепловая, отпущенная тепловыми электроцентралями (ТЭЦ)</name>
                </OKPD2>
                <purchaseCode>191770100369077360100100100013530000</purchaseCode>
                <tenderPlanInfo>
                    <plan2017Number>2019037310004350010001</plan2017Number>
                    <position2017Number>2019037310004350010000300001</position2017Number>
                </tenderPlanInfo>
                <mustPublicDiscussion>false</mustPublicDiscussion>
            </lot>
        </lots>
        <particularsActProcurement>п.8, ч.1, ст.93 44ФЗ</particularsActProcurement>
    </ns2:fcsNotification111>
</ns2:export>
  • Вопрос задан
  • 196 просмотров
Решения вопроса 1
fox_12
@fox_12 Куратор тега Python
Расставляю биты, управляю заряженными частицами
print(tree.find('.//{http://zakupki.gov.ru/oos/types/1}id').text)
# 18934116


Либо такой лайфхак:
import re
from lxml import etree

parser = etree.XMLParser(ns_clean=True)
xml = re.sub(' xmlns="[^"]+"', '', xml, count=1) # в xml - ваш реальный xml
tree = etree.fromstring(xml.encode(), parser)

print(tree.find(".//id").text)
# 18934116
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@iddqda
network engineer, netdevops
потому что namespace-ы
чтоб от них избавиться я такой метод использую:
https://github.com/jeremyschulman/xml-tutorial/blo...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы