我使用this tool从ebay XML文件制作CSV。
我已经在notepad ++中使用正则表达式删除了所有发货目的地,因为它们是不必要的。然后我删除了(<sellingStatus>|</sellingStatus>)
因为我认为这棵树太深了(我是一个XML菜鸟)。但是,当转换完成后,价格不会出现在CSV上。
以下XML示例。有人可以解释为什么价格没有被转换器拿起来,理想情况下建议使用正则表达式来修复它吗?
<?xml version='1.0' encoding='UTF-8'?>
<findItemsIneBayStoresResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.13.0</version>
<timestamp>2016-08-03T06:19:01.316Z</timestamp>
<searchResult count="97">
<item>
<itemId>152174882749</itemId>
<title>Yolande' Butterfly Blue #' print of original Watercolour , A4 size.</title>
<globalId>EBAY-GB</globalId>
<primaryCategory>
<categoryId>60437</categoryId>
<categoryName>Paintings</categoryName>
</primaryCategory>
<galleryURL>http://thumbs2.ebaystatic.com/m/m_VMlLhEdNRYkHi-6hUvbLg/140.jpg</galleryURL>
<viewItemURL>http://www.ebay.co.uk/itm/Yolande-Butterfly-Blue-print-original-Watercolour-A4-size-/152174882749</viewItemURL>
<paymentMethod>PayPal</paymentMethod>
<autoPay>false</autoPay>
<postalCode>TQ110DD</postalCode>
<location>Buckfastleigh,United Kingdom</location>
<country>GB</country>
<currentPrice currencyId="GBP">12.5</currentPrice>
<convertedCurrentPrice currencyId="GBP">12.5</convertedCurrentPrice>
<sellingState>Active</sellingState>
<timeLeft>P16DT11H53M5S</timeLeft>
<listingInfo>
<bestOfferEnabled>true</bestOfferEnabled>
<buyItNowAvailable>false</buyItNowAvailable>
<startTime>2016-07-20T18:12:06.000Z</startTime>
<endTime>2016-08-19T18:12:06.000Z</endTime>
<listingType>StoreInventory</listingType>
<gift>false</gift>
</listingInfo>
<isMultiVariationListing>false</isMultiVariationListing>
<topRatedListing>false</topRatedListing>
</item>
<item>
<itemId>152181312690</itemId>
<title>'Peacock' print of original Watercolour by Yolande, A4 size.</title>
<globalId>EBAY-GB</globalId>
<primaryCategory>
<categoryId>60437</categoryId>
<categoryName>Paintings</categoryName>
</primaryCategory>
<galleryURL>http://thumbs3.ebaystatic.com/m/m42A7QDsUeNNpkQylOnmMmg/140.jpg</galleryURL>
<viewItemURL>http://www.ebay.co.uk/itm/Peacock-print-original-Watercolour-Yolande-A4-size-/152181312690</viewItemURL>
<paymentMethod>PayPal</paymentMethod>
<autoPay>false</autoPay>
<postalCode>TQ110DD</postalCode>
<location>Buckfastleigh,United Kingdom</location>
<country>GB</country>
<currentPrice currencyId="GBP">12.5</currentPrice>
<convertedCurrentPrice currencyId="GBP">12.5</convertedCurrentPrice>
<sellingState>Active</sellingState>
<timeLeft>P21DT16H47M12S</timeLeft>
<listingInfo>
<bestOfferEnabled>true</bestOfferEnabled>
<buyItNowAvailable>false</buyItNowAvailable>
<startTime>2016-07-25T23:06:13.000Z</startTime>
<endTime>2016-08-24T23:06:13.000Z</endTime>
<listingType>StoreInventory</listingType>
<gift>false</gift>
</listingInfo>
<isMultiVariationListing>false</isMultiVariationListing>
<topRatedListing>false</topRatedListing>
</item>
答案 0 :(得分:1)
不,请请 - 请不要使用regex
来破坏您的XML。 It's very bad news.。它创造了脆弱的代码,有一天可能会破坏。
还有其他解决方案。 IMO使用脚本语言(如perl
)以您特别想要的方式进行转换,这将是最佳的。
让我们了解您的示例输出将是什么(以及一些有效的XML - 您的遗漏了关闭标记),我可以举个例子。
但它会是这样的:
#!/usr/bin/env perl
use strict;
use warnings 'all';
use XML::Twig;
my $twig = XML::Twig -> new -> parsefile('your_file.xml');
my @columns_xpath = qw ( itemId title postalCode currentPrice listingType );
print join( ",", @columns_xpath ), "\n";
foreach my $item ( $twig -> get_xpath('.//item') ) {
print join ",", (map { $item -> get_xpath(".//$_", 0 ) -> text } @columns_xpath), "\n";
}
它真的那么简单,并为您提供了更多的输出结构灵活性。 (其他语言也可以做同样的事情 - 我只提供perl
,因为我喜欢它,这是一个可靠的选择)。
注意 - 我使用xpath
进行搜索。在xpath
- 类似regex
,但专门针对XML - .//
表示在此分支下搜索&#34;。
所以.//listingType
会找到./listingInfo/listingType
- 这只适用于只有一个(因为他0
中的get_xpath
说&#39;得到仅限第一个实例)。
根据您的数据,这将会起作用。但你可以省略//
并做完全合格的&#39;路径。
从上面生成的输出是:(虽然我必须在XML的末尾添加&#39; close&#39;标记)。
itemId,title,postalCode,currentPrice,listingType
152174882749,Yolande' Butterfly Blue #' print of original Watercolour , A4 size.,TQ110DD,12.5,StoreInventory,
152181312690,'Peacock' print of original Watercolour by Yolande, A4 size.,TQ110DD,12.5,StoreInventory,
所以这里有一个简单的&#34;棍子逗号的缺陷&#34;解决问题的方法。对于输出,我们需要做正确的&#39; CSV - 使用另一个简单的可用模块:
#!/usr/bin/env perl
use strict;
use warnings 'all';
use XML::Twig;
use Text::CSV;
my $twig = XML::Twig -> new -> parsefile ( 'input.xml');
open ( my $output, '>', "results.csv" ) or die $!;
my @columns_xpath = qw ( itemId title postalCode currentPrice listingType );
my $csv = Text::CSV -> new ( {sep_char => ',', eol => "\n" });
$csv -> print ( $output, \@columns_xpath );
foreach my $item ( $twig -> get_xpath('.//item') ) {
my @row = map { $item -> get_xpath(".//$_", 0 ) -> text } @columns_xpath;
$csv -> print ( $output, \@row );
}
close ( $output );
现在我们正确地引用了CSV:
itemId,title,postalCode,currentPrice,listingType
152174882749,"Yolande' Butterfly Blue #' print of original Watercolour , A4 size.",TQ110DD,12.5,StoreInventory
152181312690,"'Peacock' print of original Watercolour by Yolande, A4 size.",TQ110DD,12.5,StoreInventory
但是要回答你原来的问题 - 是否有任何可能性,因为它sellingState
不是sellingStatus
?
答案 1 :(得分:0)
请尝试以下代码使用C#。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication6
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
const String CSV = @"c:\temp\test.csv";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
StreamWriter writer = new StreamWriter(CSV);
Boolean firstRow = true;
List<string> columnsNames = new List<string>();
foreach(XElement item in doc.Descendants().Where(x => x.Name.LocalName == "item"))
{
List<string> columns = new List<string>();
foreach (XElement element in item.Elements())
{
if (element.Name.LocalName == "listingInfo")
{
foreach (XElement listing in element.Elements())
{
columns.Add(((string)listing).Trim());
if (firstRow)
{
columnsNames.Add(listing.Name.LocalName);
}
}
}
else
{
columns.Add(((string)element).Trim());
if (firstRow)
{
columnsNames.Add(element.Name.LocalName);
}
}
}
if (firstRow)
{
writer.WriteLine(string.Join(",", columnsNames.ToArray()));
firstRow = false;
}
writer.WriteLine(string.Join(",", columns.ToArray()));
}
writer.Flush();
writer.Close();
}
}
}
&#13;