【问题标题】:How to merge 2 xml files with namespaces如何将 2 个 xml 文件与命名空间合并
【发布时间】:2014-10-07 12:41:52
【问题描述】:

我正在尝试使用 ElementTree 模块合并两个 XML 文件。以下是 XML:

a.xml:

<?xml version="1.0"?>
<ListOrdersResponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01">
  <ListOrdersResult>
    <NextToken>token</NextToken>
    <CreatedBefore>2014-10-07T08:13:11Z</CreatedBefore>
    <Orders>
      <Order>
        <AmazonOrderId>12345</AmazonOrderId>
        <SellerOrderId>R12345</SellerOrderId>
        <PurchaseDate>2014-10-02T14:40:37Z</PurchaseDate>
        <LastUpdateDate>2014-10-03T09:47:02Z</LastUpdateDate>
        <OrderStatus>Shipped</OrderStatus>
        <FulfillmentChannel>MFN</FulfillmentChannel>
        <SalesChannel>Amazon.in</SalesChannel>
        <ShipServiceLevel>IN Exp Dom 2</ShipServiceLevel>
        <ShippingAddress>
          <Name>name</Name>
          <AddressLine1>line1</AddressLine1>
          <AddressLine2>line2</AddressLine2>
          <City>Pune</City>
          <StateOrRegion>Maharashtra</StateOrRegion>
          <PostalCode>411027</PostalCode>
          <CountryCode>IN</CountryCode>
          <Phone>123456789</Phone>
        </ShippingAddress>
        <OrderTotal>
          <CurrencyCode>INR</CurrencyCode>
          <Amount>520.00</Amount>
        </OrderTotal>
        <NumberOfItemsShipped>1</NumberOfItemsShipped>
        <NumberOfItemsUnshipped>0</NumberOfItemsUnshipped>
        <PaymentExecutionDetail/>
        <PaymentMethod>Other</PaymentMethod>
        <MarketplaceId>mid</MarketplaceId>
        <BuyerEmail>email@buyer.com</BuyerEmail>
        <BuyerName>name</BuyerName>
        <ShipmentServiceLevelCategory>Expedited</ShipmentServiceLevelCategory>
        <ShippedByAmazonTFM>false</ShippedByAmazonTFM>
        <TFMShipmentStatus>Delivered</TFMShipmentStatus>
        <OrderType>StandardOrder</OrderType>
        <EarliestShipDate>2014-10-05T18:30:00Z</EarliestShipDate>
        <LatestShipDate>2014-10-07T18:29:59Z</LatestShipDate>
        <EarliestDeliveryDate>2014-10-07T18:30:00Z</EarliestDeliveryDate>
        <LatestDeliveryDate>2014-10-11T18:29:59Z</LatestDeliveryDate>
      </Order>
    </Orders>
  </ListOrdersResult>
</ListOrdersResponse>

b.xml:

<?xml version="1.0"?>
<ListOrdersByNextTokenResponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01">
  <ListOrdersByNextTokenResult>
    <NextToken>token1</NextToken>
    <CreatedBefore>2014-10-07T08:13:11Z</CreatedBefore>
    <Orders>
      <Order>
        <AmazonOrderId>oid1</AmazonOrderId>
        <PurchaseDate>2014-10-04T13:37:41Z</PurchaseDate>
        <LastUpdateDate>2014-10-06T09:52:21Z</LastUpdateDate>
        <OrderStatus>Shipped</OrderStatus>
        <FulfillmentChannel>MFN</FulfillmentChannel>
        <SalesChannel>Amazon.in</SalesChannel>
        <ShipServiceLevel>IN Std Dom 2_50k_cod</ShipServiceLevel>
        <ShippingAddress>
          <Name>name1</Name>
          <AddressLine1>line1-1</AddressLine1>
          <AddressLine2>line2-1</AddressLine2>
          <City>WADHVANCITY,SURENDRANAGAR</City>
          <StateOrRegion>Gujarat</StateOrRegion>
          <PostalCode>363035</PostalCode>
          <CountryCode>IN</CountryCode>
          <Phone>987654321</Phone>
        </ShippingAddress>
        <OrderTotal>
          <CurrencyCode>INR</CurrencyCode>
          <Amount>242.00</Amount>
        </OrderTotal>
        <NumberOfItemsShipped>1</NumberOfItemsShipped>
        <NumberOfItemsUnshipped>0</NumberOfItemsUnshipped>
        <PaymentExecutionDetail/>
        <PaymentMethod>Other</PaymentMethod>
        <MarketplaceId>mid1</MarketplaceId>
        <BuyerEmail>email1@buyer.com</BuyerEmail>
        <BuyerName>name1</BuyerName>
        <ShipmentServiceLevelCategory>Standard</ShipmentServiceLevelCategory>
        <ShippedByAmazonTFM>false</ShippedByAmazonTFM>
        <TFMShipmentStatus>PendingPickUp</TFMShipmentStatus>
        <OrderType>StandardOrder</OrderType>
        <EarliestShipDate>2014-10-05T18:30:00Z</EarliestShipDate>
        <LatestShipDate>2014-10-07T18:29:59Z</LatestShipDate>
        <EarliestDeliveryDate>2014-10-09T18:30:00Z</EarliestDeliveryDate>
        <LatestDeliveryDate>2014-10-15T18:29:59Z</LatestDeliveryDate>
      </Order>
    </Orders>
  </ListOrdersByNextTokenResult>
</ListOrdersByNextTokenResponse>

我想将b.xml 中的Orders 元素添加到a.xml 的元素中 所以,预期的输出是:

<?xml version="1.0"?>
<ListOrdersResponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01">
  <ListOrdersResult>
    <NextToken>token</NextToken>
    <CreatedBefore>2014-10-07T08:13:11Z</CreatedBefore>
    <Orders>
      <Order>
        <AmazonOrderId>12345</AmazonOrderId>
        <SellerOrderId>R12345</SellerOrderId>
        <PurchaseDate>2014-10-02T14:40:37Z</PurchaseDate>
        <LastUpdateDate>2014-10-03T09:47:02Z</LastUpdateDate>
        <OrderStatus>Shipped</OrderStatus>
        <FulfillmentChannel>MFN</FulfillmentChannel>
        <SalesChannel>Amazon.in</SalesChannel>
        <ShipServiceLevel>IN Exp Dom 2</ShipServiceLevel>
        <ShippingAddress>
          <Name>name</Name>
          <AddressLine1>line1</AddressLine1>
          <AddressLine2>line2</AddressLine2>
          <City>Pune</City>
          <StateOrRegion>Maharashtra</StateOrRegion>
          <PostalCode>411027</PostalCode>
          <CountryCode>IN</CountryCode>
          <Phone>123456789</Phone>
        </ShippingAddress>
        <OrderTotal>
          <CurrencyCode>INR</CurrencyCode>
          <Amount>520.00</Amount>
        </OrderTotal>
        <NumberOfItemsShipped>1</NumberOfItemsShipped>
        <NumberOfItemsUnshipped>0</NumberOfItemsUnshipped>
        <PaymentExecutionDetail/>
        <PaymentMethod>Other</PaymentMethod>
        <MarketplaceId>mid</MarketplaceId>
        <BuyerEmail>email@buyer.com</BuyerEmail>
        <BuyerName>name</BuyerName>
        <ShipmentServiceLevelCategory>Expedited</ShipmentServiceLevelCategory>
        <ShippedByAmazonTFM>false</ShippedByAmazonTFM>
        <TFMShipmentStatus>Delivered</TFMShipmentStatus>
        <OrderType>StandardOrder</OrderType>
        <EarliestShipDate>2014-10-05T18:30:00Z</EarliestShipDate>
        <LatestShipDate>2014-10-07T18:29:59Z</LatestShipDate>
        <EarliestDeliveryDate>2014-10-07T18:30:00Z</EarliestDeliveryDate>
        <LatestDeliveryDate>2014-10-11T18:29:59Z</LatestDeliveryDate>
      </Order>
      <Order>
        <AmazonOrderId>oid1</AmazonOrderId>
        <PurchaseDate>2014-10-04T13:37:41Z</PurchaseDate>
        <LastUpdateDate>2014-10-06T09:52:21Z</LastUpdateDate>
        <OrderStatus>Shipped</OrderStatus>
        <FulfillmentChannel>MFN</FulfillmentChannel>
        <SalesChannel>Amazon.in</SalesChannel>
        <ShipServiceLevel>IN Std Dom 2_50k_cod</ShipServiceLevel>
        <ShippingAddress>
          <Name>name1</Name>
          <AddressLine1>line1-1</AddressLine1>
          <AddressLine2>line2-1</AddressLine2>
          <City>WADHVANCITY,SURENDRANAGAR</City>
          <StateOrRegion>Gujarat</StateOrRegion>
          <PostalCode>363035</PostalCode>
          <CountryCode>IN</CountryCode>
          <Phone>987654321</Phone>
        </ShippingAddress>
        <OrderTotal>
          <CurrencyCode>INR</CurrencyCode>
          <Amount>242.00</Amount>
        </OrderTotal>
        <NumberOfItemsShipped>1</NumberOfItemsShipped>
        <NumberOfItemsUnshipped>0</NumberOfItemsUnshipped>
        <PaymentExecutionDetail/>
        <PaymentMethod>Other</PaymentMethod>
        <MarketplaceId>mid1</MarketplaceId>
        <BuyerEmail>email1@buyer.com</BuyerEmail>
        <BuyerName>name1</BuyerName>
        <ShipmentServiceLevelCategory>Standard</ShipmentServiceLevelCategory>
        <ShippedByAmazonTFM>false</ShippedByAmazonTFM>
        <TFMShipmentStatus>PendingPickUp</TFMShipmentStatus>
        <OrderType>StandardOrder</OrderType>
        <EarliestShipDate>2014-10-05T18:30:00Z</EarliestShipDate>
        <LatestShipDate>2014-10-07T18:29:59Z</LatestShipDate>
        <EarliestDeliveryDate>2014-10-09T18:30:00Z</EarliestDeliveryDate>
        <LatestDeliveryDate>2014-10-15T18:29:59Z</LatestDeliveryDate>
      </Order>
    </Orders>
  </ListOrdersResult>
</ListOrdersResponse>

我试过了:

import xml.etree.ElementTree as ET
import os
import shlex
import subprocess

tree = ET.parse("a.xml")
root = tree.getroot()

combined_xml = root

namespaces = {'resp': 'https://mws.amazonservices.com/Orders/2013-09-01'}
results = combined_xml.find("resp:ListOrdersResult", namespaces=namespaces)
insertion_point = results.find("resp:Orders", namespaces=namespaces)


tree1 = ET.parse("b.xml")
root1 = tree1.getroot()

results1 = root1.find("resp:ListOrdersByNextTokenResult", namespaces=namespaces)
order_array1 = results1.find("resp:Orders", namespaces=namespaces)

for order in order_array1:
    insertion_point.extend(order)

print ET.tostring(combined_xml)

但我得到以下输出:

<ns0:ListOrdersResponse xmlns:ns0="https://mws.amazonservices.com/Orders/2013-09-01">
  <ns0:ListOrdersResult>
    <ns0:NextToken>token</ns0:NextToken>
    <ns0:CreatedBefore>2014-10-07T08:13:11Z</ns0:CreatedBefore>
    <ns0:Orders>
      <ns0:Order>
        <ns0:AmazonOrderId>12345</ns0:AmazonOrderId>
        <ns0:SellerOrderId>R12345</ns0:SellerOrderId>
        <ns0:PurchaseDate>2014-10-02T14:40:37Z</ns0:PurchaseDate>
        <ns0:LastUpdateDate>2014-10-03T09:47:02Z</ns0:LastUpdateDate>
        <ns0:OrderStatus>Shipped</ns0:OrderStatus>
        <ns0:FulfillmentChannel>MFN</ns0:FulfillmentChannel>
        <ns0:SalesChannel>Amazon.in</ns0:SalesChannel>
        <ns0:ShipServiceLevel>IN Exp Dom 2</ns0:ShipServiceLevel>
        <ns0:ShippingAddress>
          <ns0:Name>name</ns0:Name>
          <ns0:AddressLine1>line1</ns0:AddressLine1>
          <ns0:AddressLine2>line2</ns0:AddressLine2>
          <ns0:City>Pune</ns0:City>
          <ns0:StateOrRegion>Maharashtra</ns0:StateOrRegion>
          <ns0:PostalCode>411027</ns0:PostalCode>
          <ns0:CountryCode>IN</ns0:CountryCode>
          <ns0:Phone>123456789</ns0:Phone>
        </ns0:ShippingAddress>
        <ns0:OrderTotal>
          <ns0:CurrencyCode>INR</ns0:CurrencyCode>
          <ns0:Amount>520.00</ns0:Amount>
        </ns0:OrderTotal>
        <ns0:NumberOfItemsShipped>1</ns0:NumberOfItemsShipped>
        <ns0:NumberOfItemsUnshipped>0</ns0:NumberOfItemsUnshipped>
        <ns0:PaymentExecutionDetail />
        <ns0:PaymentMethod>Other</ns0:PaymentMethod>
        <ns0:MarketplaceId>mid</ns0:MarketplaceId>
        <ns0:BuyerEmail>email@buyer.com</ns0:BuyerEmail>
        <ns0:BuyerName>name</ns0:BuyerName>
        <ns0:ShipmentServiceLevelCategory>Expedited</ns0:ShipmentServiceLevelCategory>
        <ns0:ShippedByAmazonTFM>false</ns0:ShippedByAmazonTFM>
        <ns0:TFMShipmentStatus>Delivered</ns0:TFMShipmentStatus>
        <ns0:OrderType>StandardOrder</ns0:OrderType>
        <ns0:EarliestShipDate>2014-10-05T18:30:00Z</ns0:EarliestShipDate>
        <ns0:LatestShipDate>2014-10-07T18:29:59Z</ns0:LatestShipDate>
        <ns0:EarliestDeliveryDate>2014-10-07T18:30:00Z</ns0:EarliestDeliveryDate>
        <ns0:LatestDeliveryDate>2014-10-11T18:29:59Z</ns0:LatestDeliveryDate>
      </ns0:Order>
    <ns0:AmazonOrderId>oid1</ns0:AmazonOrderId>
        <ns0:PurchaseDate>2014-10-04T13:37:41Z</ns0:PurchaseDate>
        <ns0:LastUpdateDate>2014-10-06T09:52:21Z</ns0:LastUpdateDate>
        <ns0:OrderStatus>Shipped</ns0:OrderStatus>
        <ns0:FulfillmentChannel>MFN</ns0:FulfillmentChannel>
        <ns0:SalesChannel>Amazon.in</ns0:SalesChannel>
        <ns0:ShipServiceLevel>IN Std Dom 2_50k_cod</ns0:ShipServiceLevel>
        <ns0:ShippingAddress>
          <ns0:Name>name1</ns0:Name>
          <ns0:AddressLine1>line1-1</ns0:AddressLine1>
          <ns0:AddressLine2>line2-1</ns0:AddressLine2>
          <ns0:City>WADHVANCITY,SURENDRANAGAR</ns0:City>
          <ns0:StateOrRegion>Gujarat</ns0:StateOrRegion>
          <ns0:PostalCode>363035</ns0:PostalCode>
          <ns0:CountryCode>IN</ns0:CountryCode>
          <ns0:Phone>987654321</ns0:Phone>
        </ns0:ShippingAddress>
        <ns0:OrderTotal>
          <ns0:CurrencyCode>INR</ns0:CurrencyCode>
          <ns0:Amount>242.00</ns0:Amount>
        </ns0:OrderTotal>
        <ns0:NumberOfItemsShipped>1</ns0:NumberOfItemsShipped>
        <ns0:NumberOfItemsUnshipped>0</ns0:NumberOfItemsUnshipped>
        <ns0:PaymentExecutionDetail />
        <ns0:PaymentMethod>Other</ns0:PaymentMethod>
        <ns0:MarketplaceId>mid1</ns0:MarketplaceId>
        <ns0:BuyerEmail>email1@byer.com</ns0:BuyerEmail>
        <ns0:BuyerName>name1</ns0:BuyerName>
        <ns0:ShipmentServiceLevelCategory>Standard</ns0:ShipmentServiceLevelCategory>
        <ns0:ShippedByAmazonTFM>false</ns0:ShippedByAmazonTFM>
        <ns0:TFMShipmentStatus>PendingPickUp</ns0:TFMShipmentStatus>
        <ns0:OrderType>StandardOrder</ns0:OrderType>
        <ns0:EarliestShipDate>2014-10-05T18:30:00Z</ns0:EarliestShipDate>
        <ns0:LatestShipDate>2014-10-07T18:29:59Z</ns0:LatestShipDate>
        <ns0:EarliestDeliveryDate>2014-10-09T18:30:00Z</ns0:EarliestDeliveryDate>
        <ns0:LatestDeliveryDate>2014-10-15T18:29:59Z</ns0:LatestDeliveryDate>
      </ns0:Orders>
  </ns0:ListOrdersResult>
</ns0:ListOrdersResponse>

为什么我收到ns0?此外,第二个订单缺少&lt;Order&gt; 标签。如果没有ns0,如何获得所需的输出。如果它让生活更轻松,我同意使用另一个模块的建议。:) 谢谢

【问题讨论】:

  • 我的建议是lxml。 lxml.de。 ns0 与 elementtree 顺便说一句。我也收到了。

标签: python python-2.7 elementtree


【解决方案1】:

ns0 表示“命名空间 0”——它是您的命名空间字典和“resp:tagname”术语的结果。

不过,我真的建议您使用 beautifulsoup4 - 使用 xml 会更好:

from bs4 import BeautifulSoup

soup = BeautifulSoup(open('a.xml'))
insertion_point = soup.listordersresult.orders

orders_b = BeautifulSoup(open('b.xml')).listordersbynexttokenresult.orders
# could probably just be orders_b = BeautifulSoup(open('b.xml'))

orders_to_insert = orders_b.find_all('order')
for order in orders_to_insert:
    insertion_point.append(order)
print(soup)

【讨论】:

  • 这是有效的。但是我在 XML 上得到了一个 HTML 输出。 &lt;html&gt;&lt;body&gt;&lt;listordersresponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01"&gt; &lt;listordersresult&gt;....as desired...&lt;/listordersresponse&gt;&lt;/body&gt;&lt;/html&gt;
  • 不应该,但documents 说你可以添加'xml' 作为BeautifulSoup() 对象的第二个参数,比如soup=BeautifulSoup(open('a.xml'),'xml') - 如果你安装了bs4,它应该自动虽然检测到。以前版本的 bs 对此比较了解,pip install beautifulsouppip install beautifulsoup4 之间存在差异
  • 我做了pip install beautifulsoup4。添加第二个参数后,我收到以下错误:insertion_point = soup.listordersresult.orders AttributeError: 'NoneType' object has no attribute 'orders'
  • 这很奇怪......当我运行我发布的代码片段时(在 py2.7 或 py3.4 下)它按预期工作,输出中没有 或 标记.我不确定是什么导致您的系统上的行为有所不同。
  • 此外,这会降低所有内容,所有标签名称。这是不希望的
【解决方案2】:
import xml.etree.ElementTree as ET
from StringIO import StringIO

namespaces = {'resp': 'https://mws.amazonservices.com/Orders/2013-09-01'}

tree = ET.parse("a.xml")
root = tree.getroot()

results = root.find("resp:ListOrdersResult", namespaces=namespaces)
order_array = results.find("resp:Orders", namespaces=namespaces).getchildren()

tree1 = ET.parse("b.xml")
root1 = tree1.getroot()

results1 = root1.find("resp:ListOrdersByNextTokenResult", namespaces=namespaces)
order_array1 = results1.find("resp:Orders", namespaces=namespaces).getchildren()

for order in order_array1:
    order_array.append(order)

tree.write("temp.xml")

correct_data = open("temp.xml").read().replace('ns0:', '').replace(':ns0','')
filewrite = open("combined.xml", 'w')
filewrite.write(correct_data)
filewrite.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    相关资源
    最近更新 更多