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:
...
Другие вопросы по тегам