Home > Software design >  XML beautiful soup insert_before Tag to all tables with the same name attributes
XML beautiful soup insert_before Tag to all tables with the same name attributes

Time:08-19

I have this XML structure, using python and beautifulsoup4

<?xml version="1.0" encoding="utf-8"?>

 <database name="test_testdatabase">

   <table name="products">
     <column name="product_id"> x1x </column>
   </table>

   <table name="products_en_gb">
    <column  name="product_name"> Some name 1 </column >
    <column  name="product_s_desc"> Some short description 1 </column >
  </table>
  
  <table name="products">
   <column name="product_id"> 2xx </column>
  </table>

  <table name="products_en_gb">
   <column  name="product_name"> Second product name 2 </column >
   <column  name="product_s_desc"> Second short description 2 </column >
  </table>

</database>

I would like to insert_before new tag to all tables with name name="products_en_gb" I try many different option and most success I have with these code:

newTag = soup.new_tag("table")
newTag.name = "table"
newTag['name'] = "new_table_tag"
Tag_products_en_gb = soup.find(attrs={"name": "products_en_gb"})
Tag_products_en_gb.insert_before(newTag)

This code above works, but inserts only one tag in first table, if I use soup.find_all not working

I did some experiments with following code but I cant get it work

for soup, item in zip(soup.find(attrs={"name": "products_en_gb"})), newTag):  
    soup.insert_before(item)

My desired result is following:

<?xml version="1.0" encoding="utf-8"?>

 <database name="test_testdatabase">

  <table name="products">
     <column name="product_id"> x1x </column>
  </table>

  <table name="new_table_tag">
  </table>

  <table name="products_en_gb">
    <column  name="product_name"> Some name 1 </column >
    <column  name="product_s_desc"> Some short description 1 </column >
  </table>

  <table name="products">
   <column name="product_id"> 2xx </column>
  </table>

  <table name="new_table_tag">
  </table>

  <table name="products_en_gb">
   <column  name="product_name"> Second product name 2 </column >
   <column  name="product_s_desc"> Second short description 2 </column >
  </table>

</database>

Thank you

CodePudding user response:

You should be able to get by, using something like this:

from bs4 import BeautifulSoup

doc = '''<?xml version="1.0" encoding="utf-8"?>

 <database name="test_testdatabase">

   <table name="products">
     <column name="product_id"> x1x </column>
   </table>

   <table name="products_en_gb">
    <column  name="product_name"> Some name 1 </column >
    <column  name="product_s_desc"> Some short description 1 </column >
  </table>
  
  <table name="products">
   <column name="product_id"> 2xx </column>
  </table>

  <table name="products_en_gb">
   <column  name="product_name"> Second product name 2 </column >
   <column  name="product_s_desc"> Second short description 2 </column >
  </table>

</database>
'''
soup = BeautifulSoup(doc, 'html.parser')
Tag_products_en_gb = soup.select("table[name='products_en_gb']")
for x in Tag_products_en_gb:
    newTag = soup.new_tag("table")
    newTag['name'] = "new_table_tag"
    
    x.insert_before(newTag)
print(soup)

Result:

<?xml version="1.0" encoding="utf-8"?>
<database name="test_testdatabase">
<table name="products">
<column name="product_id"> x1x </column>
</table>
<table name="new_table_tag"></table><table name="products_en_gb">
<column name="product_name"> Some name 1 </column>
<column name="product_s_desc"> Some short description 1 </column>
</table>
<table name="products">
<column name="product_id"> 2xx </column>
</table>
<table name="new_table_tag"></table><table name="products_en_gb">
<column name="product_name"> Second product name 2 </column>
<column name="product_s_desc"> Second short description 2 </column>
</table>
</database>

BeautifulSoup docs: https://beautiful-soup-4.readthedocs.io/en/latest/index.html

  • Related