在beautifulsoup标签中插入xml树字符串

时间:2019-06-11 11:05:36

标签: python xml python-3.x beautifulsoup python-3.6

我有一个xml树作为字符串。我想将这棵树插入beautifulsoup对象内的另一个标签中。

我想在标签stra内插入字符串<voucher action="Create" objview="Accounting Voucher View" vchtype="Journal">

在原始文件中,凭证标签内没有任何内容。

代码:

from bs4 import BeautifulSoup as bs

stra = r'''<DATE>20190101</DATE>
      <VOUCHERTYPENAME>Journal</VOUCHERTYPENAME>
      <VOUCHERNUMBER>5</VOUCHERNUMBER>
      <PERSISTEDVIEW>Accounting Voucher View</PERSISTEDVIEW>
      <EFFECTIVEDATE>20190101</EFFECTIVEDATE>    
      <MASTERID> 1</MASTERID>

      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>Salary Payable</LEDGERNAME>
       <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
       <AMOUNT>1000.00</AMOUNT>
       <VATEXPAMOUNT>1000.00</VATEXPAMOUNT>
      </ALLLEDGERENTRIES.LIST>'''
newsoup=bs(stra)

f = open(r"F:\Users\Administrator\Desktop\TallyJVXml.txt").read()
soup = bs(f,'lxml')
l = soup.find("voucher".lower())
l.append(stra)
print(soup)

当前输出:

<html><body><envelope>
<header>
<tallyrequest>Import Data</tallyrequest>
</header>
<importdata>
<requestdesc>
<reportname>Vouchers</reportname>
<staticvariables>
<svcurrentcompany>SOAC</svcurrentcompany>
</staticvariables>
</requestdesc>
<requestdata>
<tallymessage xmlns:udf="TallyUDF">
<voucher action="Create" objview="Accounting Voucher View" vchtype="Journal">
&lt;DATE&gt;20190101&lt;/DATE&gt;
      &lt;VOUCHERTYPENAME&gt;Journal&lt;/VOUCHERTYPENAME&gt;
      &lt;VOUCHERNUMBER&gt;5&lt;/VOUCHERNUMBER&gt;
      &lt;PERSISTEDVIEW&gt;Accounting Voucher View&lt;/PERSISTEDVIEW&gt;
      &lt;EFFECTIVEDATE&gt;20190101&lt;/EFFECTIVEDATE&gt;    
      &lt;MASTERID&gt; 1&lt;/MASTERID&gt;

      &lt;ALLLEDGERENTRIES.LIST&gt;
       &lt;LEDGERNAME&gt;Salary Payable&lt;/LEDGERNAME&gt;
       &lt;ISDEEMEDPOSITIVE&gt;No&lt;/ISDEEMEDPOSITIVE&gt;
       &lt;AMOUNT&gt;1000.00&lt;/AMOUNT&gt;
       &lt;VATEXPAMOUNT&gt;1000.00&lt;/VATEXPAMOUNT&gt;
      &lt;/ALLLEDGERENTRIES.LIST&gt;</voucher>
</tallymessage>
</requestdata>
</importdata>
</envelope>
</body></html>

所需的输出:

<ENVELOPE>
 <HEADER>
  <TALLYREQUEST>Import Data</TALLYREQUEST>
 </HEADER>
 <BODY>
  <IMPORTDATA>
   <REQUESTDESC>
    <REPORTNAME>Vouchers</REPORTNAME>
    <STATICVARIABLES>
     <SVCURRENTCOMPANY>SOAC</SVCURRENTCOMPANY>
    </STATICVARIABLES>
   </REQUESTDESC>
   <REQUESTDATA>
    <TALLYMESSAGE xmlns:UDF="TallyUDF">
     <VOUCHER VCHTYPE="Journal" ACTION="Create" OBJVIEW="Accounting Voucher View">
              <DATE>20190101</DATE>
      <VOUCHERTYPENAME>Journal</VOUCHERTYPENAME>
      <VOUCHERNUMBER>5</VOUCHERNUMBER>
      <PERSISTEDVIEW>Accounting Voucher View</PERSISTEDVIEW>
      <EFFECTIVEDATE>20190101</EFFECTIVEDATE>

      <MASTERID> 1</MASTERID>

      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>Basic Salary</LEDGERNAME>
       <ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
       <AMOUNT>-1000.00</AMOUNT>
       <VATEXPAMOUNT>-1000.00</VATEXPAMOUNT>
       <CATEGORYALLOCATIONS.LIST>
        <CATEGORY>Primary Cost Category</CATEGORY>
        <COSTCENTREALLOCATIONS.LIST>
         <NAME>Shoeb</NAME>
         <AMOUNT>-1000.00</AMOUNT>
        </COSTCENTREALLOCATIONS.LIST>
       </CATEGORYALLOCATIONS.LIST>
      </ALLLEDGERENTRIES.LIST>

      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>Salary Payable</LEDGERNAME>
       <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
       <AMOUNT>1000.00</AMOUNT>
       <VATEXPAMOUNT>1000.00</VATEXPAMOUNT>
      </ALLLEDGERENTRIES.LIST>


     </VOUCHER>
    </TALLYMESSAGE>
   </REQUESTDATA>
  </IMPORTDATA>
 </BODY>
</ENVELOPE>

如何修改代码以实现此目的?

任何建议表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:3)

data1 = '''<ENVELOPE>
 <HEADER>
  <TALLYREQUEST>Import Data</TALLYREQUEST>
 </HEADER>
 <BODY>
  <IMPORTDATA>
   <REQUESTDESC>
    <REPORTNAME>Vouchers</REPORTNAME>
    <STATICVARIABLES>
     <SVCURRENTCOMPANY>SOAC</SVCURRENTCOMPANY>
    </STATICVARIABLES>
   </REQUESTDESC>
   <REQUESTDATA>
    <TALLYMESSAGE xmlns:UDF="TallyUDF">
     <VOUCHER VCHTYPE="Journal" ACTION="Create" OBJVIEW="Accounting Voucher View">

     </VOUCHER>
    </TALLYMESSAGE>
   </REQUESTDATA>
  </IMPORTDATA>
 </BODY>
</ENVELOPE>'''


data2 = '''<DATE>20190101</DATE>
      <VOUCHERTYPENAME>Journal</VOUCHERTYPENAME>
      <VOUCHERNUMBER>5</VOUCHERNUMBER>
      <PERSISTEDVIEW>Accounting Voucher View</PERSISTEDVIEW>
      <EFFECTIVEDATE>20190101</EFFECTIVEDATE>

      <MASTERID> 1</MASTERID>

      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>Basic Salary</LEDGERNAME>
       <ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
       <AMOUNT>-1000.00</AMOUNT>
       <VATEXPAMOUNT>-1000.00</VATEXPAMOUNT>
       <CATEGORYALLOCATIONS.LIST>
        <CATEGORY>Primary Cost Category</CATEGORY>
        <COSTCENTREALLOCATIONS.LIST>
         <NAME>Shoeb</NAME>
         <AMOUNT>-1000.00</AMOUNT>
        </COSTCENTREALLOCATIONS.LIST>
       </CATEGORYALLOCATIONS.LIST>
      </ALLLEDGERENTRIES.LIST>

      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>Salary Payable</LEDGERNAME>
       <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
       <AMOUNT>1000.00</AMOUNT>
       <VATEXPAMOUNT>1000.00</VATEXPAMOUNT>
      </ALLLEDGERENTRIES.LIST>'''

from bs4 import BeautifulSoup

soup1 = BeautifulSoup(data1, 'xml')
soup2 = BeautifulSoup(data2, 'lxml')
body = soup2.select_one('body')
soup1.select_one('VOUCHER[VCHTYPE="Journal"]').append(body)
body.unwrap()

print(soup1.prettify())

打印:

<?xml version="1.0" encoding="utf-8"?>
<ENVELOPE>
 <HEADER>
  <TALLYREQUEST>
   Import Data
  </TALLYREQUEST>
 </HEADER>
 <BODY>
  <IMPORTDATA>
   <REQUESTDESC>
    <REPORTNAME>
     Vouchers
    </REPORTNAME>
    <STATICVARIABLES>
     <SVCURRENTCOMPANY>
      SOAC
     </SVCURRENTCOMPANY>
    </STATICVARIABLES>
   </REQUESTDESC>
   <REQUESTDATA>
    <TALLYMESSAGE xmlns:UDF="TallyUDF">
     <VOUCHER ACTION="Create" OBJVIEW="Accounting Voucher View" VCHTYPE="Journal">
      <date>
       20190101
      </date>
      <vouchertypename>
       Journal
      </vouchertypename>
      <vouchernumber>
       5
      </vouchernumber>
      <persistedview>
       Accounting Voucher View
      </persistedview>
      <effectivedate>
       20190101
      </effectivedate>
      <masterid>
       1
      </masterid>
      <allledgerentries.list>
       <ledgername>
        Basic Salary
       </ledgername>
       <isdeemedpositive>
        Yes
       </isdeemedpositive>
       <amount>
        -1000.00
       </amount>
       <vatexpamount>
        -1000.00
       </vatexpamount>
       <categoryallocations.list>
        <category>
         Primary Cost Category
        </category>
        <costcentreallocations.list>
         <name>
          Shoeb
         </name>
         <amount>
          -1000.00
         </amount>
        </costcentreallocations.list>
       </categoryallocations.list>
      </allledgerentries.list>
      <allledgerentries.list>
       <ledgername>
        Salary Payable
       </ledgername>
       <isdeemedpositive>
        No
       </isdeemedpositive>
       <amount>
        1000.00
       </amount>
       <vatexpamount>
        1000.00
       </vatexpamount>
      </allledgerentries.list>
     </VOUCHER>
    </TALLYMESSAGE>
   </REQUESTDATA>
  </IMPORTDATA>
 </BODY>
</ENVELOPE>

版本2-保留大写XML字符串(data1data2与前面的相同):

from bs4 import BeautifulSoup

soup1 = BeautifulSoup(data1, 'xml')
soup2 = BeautifulSoup('<HELPERTAG>' + data2 + '</HELPERTAG>', 'xml')
body = soup2.select_one('HELPERTAG')
soup1.select_one('VOUCHER[VCHTYPE="Journal"]').append(body)
body.unwrap()

print(soup1.prettify())

打印:

<?xml version="1.0" encoding="utf-8"?>
<ENVELOPE>
 <HEADER>
  <TALLYREQUEST>
   Import Data
  </TALLYREQUEST>
 </HEADER>
 <BODY>
  <IMPORTDATA>
   <REQUESTDESC>
    <REPORTNAME>
     Vouchers
    </REPORTNAME>
    <STATICVARIABLES>
     <SVCURRENTCOMPANY>
      SOAC
     </SVCURRENTCOMPANY>
    </STATICVARIABLES>
   </REQUESTDESC>
   <REQUESTDATA>
    <TALLYMESSAGE xmlns:UDF="TallyUDF">
     <VOUCHER ACTION="Create" OBJVIEW="Accounting Voucher View" VCHTYPE="Journal">
      <DATE>
       20190101
      </DATE>
      <VOUCHERTYPENAME>
       Journal
      </VOUCHERTYPENAME>
      <VOUCHERNUMBER>
       5
      </VOUCHERNUMBER>
      <PERSISTEDVIEW>
       Accounting Voucher View
      </PERSISTEDVIEW>
      <EFFECTIVEDATE>
       20190101
      </EFFECTIVEDATE>
      <MASTERID>
       1
      </MASTERID>
      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>
        Basic Salary
       </LEDGERNAME>
       <ISDEEMEDPOSITIVE>
        Yes
       </ISDEEMEDPOSITIVE>
       <AMOUNT>
        -1000.00
       </AMOUNT>
       <VATEXPAMOUNT>
        -1000.00
       </VATEXPAMOUNT>
       <CATEGORYALLOCATIONS.LIST>
        <CATEGORY>
         Primary Cost Category
        </CATEGORY>
        <COSTCENTREALLOCATIONS.LIST>
         <NAME>
          Shoeb
         </NAME>
         <AMOUNT>
          -1000.00
         </AMOUNT>
        </COSTCENTREALLOCATIONS.LIST>
       </CATEGORYALLOCATIONS.LIST>
      </ALLLEDGERENTRIES.LIST>
      <ALLLEDGERENTRIES.LIST>
       <LEDGERNAME>
        Salary Payable
       </LEDGERNAME>
       <ISDEEMEDPOSITIVE>
        No
       </ISDEEMEDPOSITIVE>
       <AMOUNT>
        1000.00
       </AMOUNT>
       <VATEXPAMOUNT>
        1000.00
       </VATEXPAMOUNT>
      </ALLLEDGERENTRIES.LIST>
     </VOUCHER>
    </TALLYMESSAGE>
   </REQUESTDATA>
  </IMPORTDATA>
 </BODY>
</ENVELOPE>