使用元素树编辑具有现有命名空间的 XML 文件 - 我最终创建了我不知道、不想要和不需要的新外部命名空间

using Element Tree to edit the XML file with existing namespaces - I end up having new foreign namespaces created that I do not know, want and need

提问人:zstm284 提问时间:7/28/2023 最后编辑:Jim Garrisonzstm284 更新时间:7/29/2023 访问量:82

问:

我有一个正在解析和编辑的XML文件(通过添加节点)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="ns" xmlns:ns1="ns1">
<soapenv:Body>
    <ns:CreateUpdateCustomer>
        <ns:Request>
            <ns:CustomerGroupReference referenceId="1">
                <ns1:CompanyInfo>
                    <ns1:ExternalCompanyID>111</ns1:ExternalCompanyID>
                </ns1:CompanyInfo>
                <ns1:CustomerGroupName>1111</ns1:CustomerGroupName>
            </ns:CustomerGroupReference>
            <ns:Customer>
                <ns1:CustomerReference referenceId="1">
                    <ns1:CustomerNumber>2222</ns1:CustomerNumber>
                </ns1:CustomerReference>
                <ns1:Detail>
                    <ns1:CustomerName>Name1</ns1:CustomerName>
                    <ns1:CustomerNumber>Number1</ns1:CustomerNumber>
                    <ns1:Country>CountryName</ns1:Country>
                    <ns1:Address1>Address1</ns1:Address1>
                    <ns1:Address2>Address2</ns1:Address2>
                    <ns1:Region>Region</ns1:Region>
                    <ns1:City>City</ns1:City>
                    <ns1:ZipCode>ZipCode</ns1:ZipCode>
                    <ns1:ContactName>ContactName</ns1:ContactName>
                    <ns1:ContactEmail>ContactEmail</ns1:ContactEmail>
                    <ns1:ContactPhone>ContactPhone</ns1:ContactPhone>
                </ns1:Detail>
            </ns:Customer>
        </ns:Request>
    </ns:CreateUpdateCustomer>
</soapenv:Body></soapenv:Envelope>

我使用下面的代码来填充文件

import xml.etree.ElementTree as ET
import pandas as pd

tree = ET.parse(r'Customer Request.xml')

root = tree.getroot()

dfXL = Alteryx.read("#1")


namespaces = {'ns1':'ns1',
                    'ns':'ns'}

print('Below we are parsing through all of the template nodes')


for item in root:
    if 'Body' in item.tag:
        for CreateUpdateCustomer in item:
            namespace = namespaces['ns']
            tagRequestName = '{' + '' + namespace + '}Request'
            for CustGroupRefId in dfXL['CustomerGroupReference referenceId'].unique().tolist():
                RequestElement = ET.Element(tagRequestName)
                dfCustGroup  = dfXL[dfXL['CustomerGroupReference referenceId'] == CustGroupRefId] 
                namespace = namespaces['ns']
                tagCustomerGroupReferenceName = '{' + '' + namespace + '}CustomerGroupReference'
                CustomerGroupReferenceElement = ET.Element(tagCustomerGroupReferenceName)
                CustomerGroupReferenceElement.set('referenceId',str(int(CustGroupRefId)))
                
                namespace = namespaces['ns1']
                tagCompanyInfoName = '{' + '' + namespace + '}CompanyInfo'

                CompanyInfoElement = ET.Element(tagCompanyInfoName)
                
                namespace = namespaces['ns1']
                tagExternalCompanyIDName = '{' + '' + namespace + '}ExternalCompanyID'

                ExternalCompanyIDElement = ET.Element(tagExternalCompanyIDName)

                firstOfTheList = dfCustGroup['ExternalCompanyID'].unique().tolist()

                ExternalCompanyIDElement.text = firstOfTheList[0]
                    
                CompanyInfoElement.append(ExternalCompanyIDElement)

                namespace = namespaces['ns1']
                tagCustomerGroupNameName = '{' + '' + namespace + '}CustomerGroupName'

                CustomerGroupNameElement = ET.Element(tagCustomerGroupNameName)
                firstOfTheList = dfCustGroup['CustomerGroupName'].unique().tolist()

                CustomerGroupNameElement.text = firstOfTheList[0]
                    
                CustomerGroupReferenceElement.append(CompanyInfoElement)

                CustomerGroupReferenceElement.append(CustomerGroupNameElement)
                
                RequestElement.append(CustomerGroupReferenceElement)
                
                for CustomerReferenceId in dfCustGroup['CustomerReference referenceId'].unique().tolist():
                    for index, row in dfCustGroup.iterrows():
                        if CustomerReferenceId == row['CustomerReference referenceId']:
                            namespace = namespaces['ns']
                            tagCustomerName = '{' + '' + namespace + '}Customer'

                            CustomerElement = ET.Element(tagCustomerName)

                            namespace = namespaces['ns1']
                            tagCustomerReferenceName = '{' + '' + namespace + '}CustomerReference'

                            CustomerReferenceElement = ET.Element(tagCustomerReferenceName)
                            CustomerReferenceElement.set('referenceId',str(int(CustomerReferenceId)))
                            
                            namespace = namespaces['ns1']
                            tagCustomerNumberName = '{' + '' + namespace + '}CustomerNumber'

                            CustomerNumberElement = ET.Element(tagCustomerNumberName)
                            CustomerNumberElement.text = str(row['CustomerNumber'])
                            
                            CustomerReferenceElement.append(CustomerNumberElement)

                            CustomerElement.append(CustomerReferenceElement)

                            namespace = namespaces['ns1']
                            tagDetailName = '{' + '' + namespace + '}Detail'

                            DetailElement = ET.Element(tagDetailName)

                            namespace = namespaces['ns1']
                            tagCustomerNameName = '{' + '' + namespace + '}CustomerName'

                            CustomerNameElement = ET.Element(tagCustomerNameName)
                            CustomerNameElement.text = str(row['CustomerName'])

                            DetailElement.append(CustomerNameElement)
                            
                            namespace = namespaces['ns1']
                            tagCustomerNumberName = '{' + '' + namespace + '}CustomerNumber'

                            CustomerNumberElement = ET.Element(tagCustomerNumberName)
                            CustomerNumberElement.text = str(row['CustomerNumber'])

                            DetailElement.append(CustomerNumberElement)
                            
                            namespace = namespaces['ns1']
                            tagCountryName = '{' + '' + namespace + '}Country'

                            CountryElement = ET.Element(tagCountryName)
                            CountryElement.text = str(row['Country'])

                            DetailElement.append(CountryElement)
                            
                            namespace = namespaces['ns1']
                            tagAddress1Name = '{' + '' + namespace + '}Address1'

                            Address1Element = ET.Element(tagAddress1Name)
                            Address1Element.text = str(row['Address1'])

                            DetailElement.append(Address1Element)
                            
                            namespace = namespaces['ns1']
                            tagAddress2Name = '{' + '' + namespace + '}Address2'

                            Address2Element = ET.Element(tagAddress2Name)
                            Address2Element.text = str(row['Address2'])

                            DetailElement.append(Address2Element)
                            
                            namespace = namespaces['ns1']
                            tagRegionName = '{' + '' + namespace + '}Region'

                            RegionElement = ET.Element(tagRegionName)
                            RegionElement.text = str(row['Region'])

                            DetailElement.append(RegionElement)
                            
                            namespace = namespaces['ns1']
                            tagCityName = '{' + '' + namespace + '}City'

                            CityElement = ET.Element(tagCityName)
                            CityElement.text = str(row['City'])

                            DetailElement.append(CityElement)
                            
                            namespace = namespaces['ns1']
                            tagZipCodeName = '{' + '' + namespace + '}ZipCode'

                            ZipCodeElement = ET.Element(tagZipCodeName)
                            ZipCodeElement.text = str(row['ZipCode'])
 
                            DetailElement.append(ZipCodeElement)
                            
                            namespace = namespaces['ns1']
                            tagContactNameName = '{' + '' + namespace + '}ContactName'

                            ContactNameElement = ET.Element(tagContactNameName)
                            ContactNameElement.text = str(row['ContactName'])

                            DetailElement.append(ContactNameElement)
                            
                            namespace = namespaces['ns1']
                            tagContactEmailName = '{' + '' + namespace + '}ContactEmail'

                            ContactEmailElement = ET.Element(tagContactEmailName)
                            ContactEmailElement.text = str(row['ContactEmail'])

                            DetailElement.append(ContactEmailElement)
                            
                            namespace = namespaces['ns1']
                            tagContactPhoneName = '{' + '' + namespace + '}ContactPhone'

                            ContactPhoneElement = ET.Element(tagContactPhoneName)
                            ContactPhoneElement.text = str(row['ContactPhone'])

                            DetailElement.append(ContactPhoneElement)
                            
                            CustomerElement.append(DetailElement)

                            RequestElement.append(CustomerElement)

                CreateUpdateCustomer.append(RequestElement)

tree = ET.ElementTree(root)

with open(r'Customer.xml', 'w') as f:
    tree.write(f, encoding='unicode')

文件最终被正确填充,但是,我在新文件中的命名空间是错误的、打乱的和偏移的。另外,我得到了 2 个新命名空间,如下例所示:

文件的结果部分如下 - 我的问题是原始命名空间被重命名(ns 和 ns1)并创建了几个新的命名空间

<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns3="ns1" xmlns:ns4="ns">
    <ns0:Body>
        <ns3:CreateUpdateCustomer>
        <ns3:Request>
            <ns3:CustomerGroupReference referenceId="1">
            <ns4:CompanyInfo>
                <ns4:ExternalCompanyID>100</ns4:ExternalCompanyID>
            </ns4:CompanyInfo>
            <ns4:CustomerGroupName>1111</ns4:CustomerGroupName>
            </ns3:CustomerGroupReference>
                <ns3:Customer>
                    <ns4:CustomerReference referenceId="1">
                        <ns4:CustomerNumber>2222</ns4:CustomerNumber>
                    </ns4:CustomerReference>
                    <ns4:Detail>
                        <ns4:CustomerName>3333</ns4:CustomerName>
                        <ns4:CustomerNumber>Number</ns4:CustomerNumber>
                        <ns4:Country>aaa</ns4:Country>
                        <ns4:Address1>Address1</ns4:Address1>
                        <ns4:Address2>Address2</ns4:Address2>
                        <ns4:Region>Region</ns4:Region>
                        <ns4:City>City</ns4:City>
                        <ns4:ZipCode>ZipCode</ns4:ZipCode>          
                        <ns4:ContactName>ContactName</ns4:ContactName>
                        <ns4:ContactEmail>ContactEmail</ns4:ContactEmail>
                        <ns4:ContactPhone>ContactPhone</ns4:ContactPhone>
                    </ns4:Detail>
                </ns3:Customer>
        </ns3:Request>
        </ns3:CreateUpdateCustomer>
    </ns0:Body>
</ns0:Envelope>

请帮助我了解问题并为我指出正确的方向。我使用的是旧的 python 包吗?我应该以不同的方式添加命名空间吗?我应该以不同的方式解析文件吗?

Python XML 命名空间 elementtree

评论

1赞 WombatPM 7/28/2023
在解析之前注册命名空间。查看 stackoverflow.com/questions/8983041/...
0赞 Hermann12 7/28/2023
我们需要一个最小的工作示例,显示效果。Alteryx.read() 在哪里?
0赞 Hermann12 7/29/2023
带有数字是内部名称,不应使用它。ns

答:

2赞 Hermann12 7/29/2023 #1

如建议的评论中所示,您必须 ,例如:register_namespace()

import xml.etree.ElementTree as ET

tree = ET.parse('Customer Request_In.xml')
root = tree.getroot()

namespaces = {node[0]: node[1] for event, node in ET.iterparse('Customer Request_In.xml', events=['start-ns'])}
print("My Namespaces:", namespaces,'\n')
for ns in namespaces:
    ET.register_namespace(ns, namespaces[ns])

ExternalCompanyID = root.find('.//uli:ExternalCompanyID', namespaces)
ExternalCompanyID.text = '100'

CustomerName = root.find('.//uli:CustomerName', namespaces)
CustomerName.text = '3333'

Country = root.find('.//uli:Country', namespaces)
Country.text = 'aaa'

ET.dump(root)

tree1 = ET.ElementTree(root)
ET.indent(tree1, space= '  ')
tree1.write('Customer.xml', encoding="utf-8")

输入 xml 文件:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hugo="hugo" xmlns:uli="uli">
  <soapenv:Body>
    <hugo:CreateUpdateCustomer>
      <hugo:Request>
        <hugo:CustomerGroupReference referenceId="1">
          <uli:CompanyInfo>
            <uli:ExternalCompanyID>111</uli:ExternalCompanyID>
          </uli:CompanyInfo>
          <uli:CustomerGroupName>1111</uli:CustomerGroupName>
        </hugo:CustomerGroupReference>
        <hugo:Customer>
          <uli:CustomerReference referenceId="1">
            <uli:CustomerNumber>2222</uli:CustomerNumber>
          </uli:CustomerReference>
          <uli:Detail>
            <uli:CustomerName>Name1</uli:CustomerName>
            <uli:CustomerNumber>Number1</uli:CustomerNumber>
            <uli:Country>CountryName</uli:Country>
            <uli:Address1>Address1</uli:Address1>
            <uli:Address2>Address2</uli:Address2>
            <uli:Region>Region</uli:Region>
            <uli:City>City</uli:City>
            <uli:ZipCode>ZipCode</uli:ZipCode>
            <uli:ContactName>ContactName</uli:ContactName>
            <uli:ContactEmail>ContactEmail</uli:ContactEmail>
            <uli:ContactPhone>ContactPhone</uli:ContactPhone>
          </uli:Detail>
        </hugo:Customer>
      </hugo:Request>
    </hugo:CreateUpdateCustomer>
  </soapenv:Body>
</soapenv:Envelope>

输出文件:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:hugo="hugo" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:uli="uli">
  <soapenv:Body>
    <hugo:CreateUpdateCustomer>
      <hugo:Request>
        <hugo:CustomerGroupReference referenceId="1">
          <uli:CompanyInfo>
            <uli:ExternalCompanyID>100</uli:ExternalCompanyID>
          </uli:CompanyInfo>
          <uli:CustomerGroupName>1111</uli:CustomerGroupName>
        </hugo:CustomerGroupReference>
        <hugo:Customer>
          <uli:CustomerReference referenceId="1">
            <uli:CustomerNumber>2222</uli:CustomerNumber>
          </uli:CustomerReference>
          <uli:Detail>
            <uli:CustomerName>3333</uli:CustomerName>
            <uli:CustomerNumber>Number1</uli:CustomerNumber>
            <uli:Country>aaa</uli:Country>
            <uli:Address1>Address1</uli:Address1>
            <uli:Address2>Address2</uli:Address2>
            <uli:Region>Region</uli:Region>
            <uli:City>City</uli:City>
            <uli:ZipCode>ZipCode</uli:ZipCode>
            <uli:ContactName>ContactName</uli:ContactName>
            <uli:ContactEmail>ContactEmail</uli:ContactEmail>
            <uli:ContactPhone>ContactPhone</uli:ContactPhone>
          </uli:Detail>
        </hugo:Customer>
      </hugo:Request>
    </hugo:CreateUpdateCustomer>
  </soapenv:Body>
</soapenv:Envelope>