Удалить тег, если атрибут существует - PullRequest
0 голосов
/ 03 августа 2020

У меня есть файл xml, который выглядит, как показано ниже

<?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <identificationInfo>
      <MD_DataIdentification>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString>Keyword1</gco:CharacterString>
               </keyword>
            </MD_Keywords>
         </descriptiveKeywords>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString />
               </keyword>
               <thesaurusName uuidref="723f6998-058e-11dc-8314-0800200c9a66" />
            </MD_Keywords>
         </descriptiveKeywords>
      </MD_DataIdentification>
   </identificationInfo>
</MD_Metadata>

Я бы хотел сделать, если xml содержит атрибут uuidref , я бы хотел Удалите весь второй тег, поэтому мой результат будет похож на

<?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <identificationInfo>
      <MD_DataIdentification>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString>Keyword1</gco:CharacterString>
               </keyword>
            </MD_Keywords>
         </descriptiveKeywords>
      </MD_DataIdentification>
   </identificationInfo>
</MD_Metadata>

Моя проблема в том, что когда я пытаюсь использовать xpath и нахожу атрибут uuidref, ничего не возвращается. Когда я смотрю на теги

for el in tree.iter():
 print el.tag

, я получаю следующее

{http://www.isotc211.org/2005/gmd}MD_Metadata
{http://www.isotc211.org/2005/gmd}identificationInfo
{http://www.isotc211.org/2005/gmd}MD_DataIdentification    
{http://www.isotc211.org/2005/gmd}descriptiveKeywords    
{http://www.isotc211.org/2005/gmd}MD_Keywords    
{http://www.isotc211.org/2005/gmd}keyword    
{http://www.isotc211.org/2005/gco}CharacterString    
{http://www.isotc211.org/2005/gmd}descriptiveKeywords    
{http://www.isotc211.org/2005/gmd}MD_Keywords    
{http://www.isotc211.org/2005/gmd}keyword    
{http://www.isotc211.org/2005/gco}CharacterString    
{http://www.isotc211.org/2005/gmd}thesaurusName

Когда я пытаюсь использовать xpath с указанным тегом

root.xpath("//{http://www.isotc211.org/2005/gmd}descriptiveKeywords")

, я получаю следующее XPathEvalError: недопустимое выражение

Итак, мои вопросы:

  1. как удалить весь описательный тег, если он содержит атрибут uuidref
  2. Почему к тегам добавляются URL-адреса?

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

Другой метод, который дает те же результаты в версии 2.7 и 3 +

from simplified_scrapy import SimplifiedDoc, utils, req
xml = '''
<?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <identificationInfo>
      <MD_DataIdentification>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString>Keyword1</gco:CharacterString>
               </keyword>
            </MD_Keywords>
         </descriptiveKeywords>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString />
               </keyword>
               <thesaurusName uuidref="723f6998-058e-11dc-8314-0800200c9a66" />
            </MD_Keywords>
         </descriptiveKeywords>
      </MD_DataIdentification>
   </identificationInfo>
</MD_Metadata>
'''
doc = SimplifiedDoc(xml)
els = doc.getElementsByReg(' uuidref="')
for el in els:
  el.getParent(tag='descriptiveKeywords').repleaceSelf('')
print (doc.html)

Результат:

<?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <identificationInfo>
      <MD_DataIdentification>
         <descriptiveKeywords>
            <MD_Keywords>
               <keyword>
                  <gco:CharacterString>Keyword1</gco:CharacterString>
               </keyword>
            </MD_Keywords>
         </descriptiveKeywords>
         
      </MD_DataIdentification>
   </identificationInfo>
</MD_Metadata>
0 голосов
/ 03 августа 2020

Вы можете выполнить фильтрацию следующим образом:

from lxml import etree as et

# Read the XML file
parser = et.XMLParser(remove_blank_text=True)
ns = {'gmd': 'http://www.isotc211.org/2005/gmd'}
tree = et.parse('Input.xml', parser)
root = tree.getroot()
# Processing loop
for it in root.findall('.//gmd:descriptiveKeywords', ns):
    if it.find('.//*[@uuidref]') is not None:
        it.getparent().remove(it)
# Print the result
print(et.tostring(root, method='xml', encoding='unicode', pretty_print=True))

Обратите внимание, что ваш XML - это пространство имен , поэтому для ссылки на любой элемент с пространством имен (даже по умолчанию ) вы должны:

  • определить словарь пространства имен (я назвал его ns ),
  • указать имена элементов с правильным префиксом пространства имен,
  • передайте указанный выше словарь в качестве второго параметра (например) findall .

Результат:

<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd"
    xmlns:gco="http://www.isotc211.org/2005/gco">
  <identificationInfo>
    <MD_DataIdentification>
      <descriptiveKeywords>
        <MD_Keywords>
          <keyword>
            <gco:CharacterString>Keyword1</gco:CharacterString>
          </keyword>
        </MD_Keywords>
      </descriptiveKeywords>
    </MD_DataIdentification>
  </identificationInfo>
</MD_Metadata>

Внимание: я написал приведенный выше код используя Python 3,8 . Не уверен, будет ли работать в версии 2.7 . Если нет, возможно, вам стоит подумать об обновлении программного обеспечения.

...