如何使用Nokogiri合并两个XML文件

时间:2020-04-27 18:15:41

标签: ruby xml xpath nokogiri

我正在尝试将两个独立但相关的文件与Nokogiri合并。如果“ ItemNumber”相同,我想组合“产品”和“产品定价”。

我加载了文档,但是我不知道如何合并两者。

产品文件:

<Products>
  <Product>
    <Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
    <ProductTypeId>0</ProductTypeId>
    <Description>This single bit curved grip axe handle is made for 3 to 5 pound axes. A good quality replacement handle made of American hickory with a natural wax finish. Hardwood handles do not conduct electricity and American Hickory is known for its strength, elasticity and ability to absorb shock. These handles provide exceptional value and economy for homeowners and other occasional use applications. Each Link handle comes with the required wedges, rivets, or epoxy needed for proper application of the tool head.</Description>
    <ActiveFlag>Y</ActiveFlag>
    <ImageFile>100024.jpg</ImageFile>
    <ItemNumber>100024</ItemNumber>
    <ProductVariants>
      <ProductVariant>
        <Sku>100024</Sku>
        <ColorName></ColorName>
        <SizeName></SizeName>
        <SequenceNo>0</SequenceNo>
        <BackOrderableFlag>N</BackOrderableFlag>
        <InventoryLevel>0</InventoryLevel>
        <ColorCode></ColorCode>
        <SizeCode></SizeCode>
        <TaxableFlag>Y</TaxableFlag>
        <VariantPromoGroupCode></VariantPromoGroupCode>
        <PricingGroupCode></PricingGroupCode>
        <StartDate xsi:nil="true"></StartDate>
        <EndDate xsi:nil="true"></EndDate>
        <ActiveFlag>Y</ActiveFlag>
      </ProductVariant>
    </ProductVariants>
  </Product>
</Products>

产品定价字段:

<ProductPricing>
  <ItemNumber>100024</ItemNumber>
  <AcquisitionCost>8.52</AcquisitionCost>
  <MemberCost>10.7</MemberCost>
  <Price>14.99</Price>
  <SalePrice xsi:nil="true"></SalePrice>
  <SaleCode>0</SaleCode>
</ProductPricing>

我正在寻找生成这样的文件:

<Products>
  <Product>
    <Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
    <ProductTypeId>0</ProductTypeId>
    <Description>This single bit curved grip axe handle is made for 3 to 5 pound axes. A good quality replacement handle made of American hickory with a natural wax finish. Hardwood handles do not conduct electricity and American Hickory is known for its strength, elasticity and ability to absorb shock. These handles provide exceptional value and economy for homeowners and other occasional use applications. Each Link handle comes with the required wedges, rivets, or epoxy needed for proper application of the tool head.</Description>
    <ActiveFlag>Y</ActiveFlag>
    <ImageFile>100024.jpg</ImageFile>
    <ItemNumber>100024</ItemNumber>
    <ProductVariants>
      <ProductVariant>
        <Sku>100024</Sku>
        <ColorName></ColorName>
        <SizeName></SizeName>
        <SequenceNo>0</SequenceNo>
        <BackOrderableFlag>N</BackOrderableFlag>
        <InventoryLevel>0</InventoryLevel>
        <ColorCode></ColorCode>
        <SizeCode></SizeCode>
        <TaxableFlag>Y</TaxableFlag>
        <VariantPromoGroupCode></VariantPromoGroupCode>
        <PricingGroupCode></PricingGroupCode>
        <StartDate xsi:nil="true"></StartDate>
        <EndDate xsi:nil="true"></EndDate>
        <ActiveFlag>Y</ActiveFlag>
      </ProductVariant>
    </ProductVariants>
  </Product>
  <ProductPricing>
    <ItemNumber>100024</ItemNumber>
    <AcquisitionCost>8.52</AcquisitionCost>
    <MemberCost>10.7</MemberCost>
    <Price>14.99</Price>
    <SalePrice xsi:nil="true"></SalePrice>
    <SaleCode>0</SaleCode>
  </ProductPricing>
</Products>

这是我到目前为止的代码:

require 'csv'
require 'nokogiri'

xml = File.read('lateApril-product-pricing.xml')
xml2 = File.read('lateApril-master-date')

doc = Nokogiri::XML(xml)
doc2 = Nokogiri::XML(xml2)

pricing_data = []
item_number = []

doc.xpath('//ProductsPricing/ProductPricing').each do |file|

  itemNumber = file.xpath('./ItemNumber').first.text
  variant_Price = file.xpath('./Price').first.text

  pricing_data << [ itemNumber, variant_Price ]

  item_number << [ itemNumber ]
end 

puts item_number ## This prints all the item number but i have no idea how to loop through them and combine them with Product XML

doc2.xpath('//Products/Product').each do |file|
  itemNumber = file.xpath('./ItemNumber').first.text #not sure how to write the conditions here since i don't have pricing fields available in this method
end 

1 个答案:

答案 0 :(得分:0)

尝试一下:

puts doc1.to_xml

# >> <?xml version="1.0"?>
# >> <Products>
# >>   <Product>
# >>     <Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
# >>   </Product><ProductPricing>
# >>   <ItemNumber>100024</ItemNumber>
# >> </ProductPricing>
# >> </Products>

这将导致:

<ItemNumber>

,当您询问时,请将示例输入和预期的结果输出剥离为绝对的,裸露的,最小的。除此之外,任何其他事情都会浪费空间,时间和大脑CPU。

这是未经测试的代码,但是如果要合并两个包含 multi require 'nokogiri' doc1 = Nokogiri::XML(<<EOT) <Products> <Product> <Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name> <ItemNumber>100024</ItemNumber> </Product> </Products> EOT doc2 = Nokogiri::XML(<<EOT) <ProductPricing> <ItemNumber>100024</ItemNumber> </ProductPricing> EOT # build a hash containing the item numbers in doc1 for each product doc1_products_by_item_numbers = doc1.search('Product').map { |product| item_number = product.at('ItemNumber').value [ item_number, product ] }.to_hash # build a hash containing the item numbers in doc2 for each product pricing doc2_products_by_item_numbers = doc2.search('ProductPricing').map { |pricing| item_number = pricing.at('ItemNumber').value [ item_number, pricing ] }.to_hash # append doc2 entries to doc1 after each product based on item numbers doc1_products_by_item_numbers.keys.each { |k| doc1_products_by_item_numbers[k].add_next_sibling(doc2_products_by_item_numbers[k]) } 个节点的文件,这就是我要开始的地方:

public static void main(String[] args) {

    ArrayList<Employee>al=new ArrayList<>();
    ArrayList<Employee>all=new ArrayList<>();

    Add(al);
    Avg(al);
    Count(al,all);
    Arrange(al);
}

static void Add(ArrayList<Employee> arr){
        Scanner s=new Scanner(System.in);
         for(int i=0;i<2;i++)
         arr.add(new Employee(s.next(),s.next(),s.nextInt()));

}

 static class Employee{
     String name;
     String department;
     Integer salary;

     Employee(String name,String department,Integer salary){
      this.name=name;
      this.department=department;
      this.salary=salary;
 }
相关问题