Python - Как подсчитать элементы атрибута XML с ограниченными значениями
Я пытаюсь сосчитать только теги файлов с атрибутом кода, большим или равным 10. Ниже мой код:-
from xml.dom.minidom import parse, parseString
import xml.dom.minidom
DOMTree = xml.dom.minidom.parse("param.xml")
group = DOMTree.documentElement
code_line_10=[0,1,2,3,4,5,6,7,8,9]
num_source_file = 0
for file in group.getElementsByTagName("file"):
if file.hasAttribute("code"):
attribute_value = file.getAttribute("code")
if attribute_value not in code_line:
num_source_file += 1
print(num_source_file)
Это фрагмент файла XML, который я использую:
<?xml version="1.0"?><results>
<files>
<file name="cadasta-platform/cadasta/templates/allauth/account/password_set.html" blank="5" comment="0" code="11" language="HTML" />
<file name="cadasta-platform/cadasta/templates/allauth/openid/login.html" blank="7" comment="0" code="11" language="HTML" />
<file name="cadasta-platform/cadasta/resources/tests/test_views_mixins.py" blank="4" comment="0" code="11" language="Python" />
<file name="cadasta-platform/cadasta/core/tests/test_translations.py" blank="2" comment="0" code="11" language="Python" />
<file name="cadasta-platform/cadasta/organization/urls/default/users.py" blank="2" comment="0" code="11" language="Python" />
<file name="cadasta-platform/cadasta/core/node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins/_alerts.scss" blank="2" comment="1" code="11" language="SASS" />
<file name="cadasta-platform/cadasta/resources/tests/utils.py" blank="2" comment="0" code="11" language="Python" />
<file name="cadasta-platform/cadasta/core/static/js/rel_tenure.js" blank="2" comment="1" code="11" language="Javascript" />
<file name="cadasta-platform/cadasta/templates/party/relationship_resources_new.html" blank="3" comment="0" code="11" language="HTML" />
<file name="cadasta-platform/functional_tests/pages/AccountInactive.py" blank="6" comment="1" code="11" language="Python" />
<file name="cadasta-platform/cadasta/core/management/commands/loadsite.py" blank="3" comment="0" code="10" language="Python" />
<file name="cadasta-platform/cadasta/core/node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins/_hide-text.scss" blank="2" comment="9" code="10" language="SASS" />
<file name="cadasta-platform/functional_tests/projects/test_project.py" blank="13" comment="109" code="0" language="Python" />
После выполнения приведенного выше кода он будет считать все теги файлов в документе xml, включая те, которые я хочу исключить. Что я не правильно делаю?
3 ответа
Используйте библиотеку, которая поддерживает xpath, например lxml, тогда вы можете делать что-то вроде:
from lxml import etree
tree = etree.parse("param.xml")
print len(tree.getroot().xpath("//file[not(@code>0 and @code<10)]"))
file.getAttribute("code")
возвращается str
объект и '1' in [1]
является False
, Теперь есть несколько способов, как решить вашу проблему.
Сначала плохие решения:
- чередовать
code_line_10=[0,1,..,9]
вcode_line_10=['0','1',..,'9']
, - + Изменить
if attribute_value not in code_line:
вif int(attribute_value) not in code_line:
(будьте осторожны, если атрибут кода не конвертируется в int, это вызывает исключение)
В обоих решениях алгоритм все равно должен пройти через все элементы в списке и сравнить элементы один за другим, и это занимает некоторое время. Более быстрое решение - просто сравнить значение с оператором. <=
, Таким образом, вы можете чередовать, если в if int(attribute_value) >= 10:
(опять же, если атрибут кода не конвертируется в int, это вызывает исключение)
getAttribute возвращает значение в виде строки. Попробуйте что-то вроде:
...
attribute_value = file.getAttribute("code")
if int(attribute_value) <= 10:
...