@Before可能会有一些重复的问题建议,我不认为是这样的情况可能先读一下,我会尽量做到尽可能简短.标题给出了基本概念.
这是一个示例XML(案例1):
<root>
<Item>
<ItemID>4504216603</ItemID>
<ListingDetails>
<StartTime>10:00:10.000Z</StartTime>
<EndTime>10:00:30.000Z</EndTime>
<ViewItemURL>http://url</ViewItemURL>
....
</item>
Run Code Online (Sandbox Code Playgroud)
这是一个示例XML(案例2):
<Item>
<ItemID>4504216604</ItemID>
<ListingDetails>
<StartTime>10:30:10.000Z</StartTime>
<!-- Start difference from case 1 -->
<averages>
<AverageTime>value1</AverageTime>
<category type="TX">9823</category>
<category type="TY">9112</category>
<AveragePrice>value2</AveragePrice>
</averages>
<!-- End difference from case 1 -->
<EndTime>11:00:10.000Z</EndTime>
<ViewItemURL>http://url</ViewItemURL>
....
</item>
</root>
Run Code Online (Sandbox Code Playgroud)
我从谷歌借用了这个XML,反正我的对象并不总是一样的,有时还有像case2这样的额外元素.现在我想从这两种情况中生成这样的CSV:
ItemID,StartTime,EndTime,ViewItemURL,AverageTime,AveragePrice
4504216603,10:00:10.000Z,10:00:30.000Z,http://url
4504216604,10:30:10.000Z,11:00:10.000Z,http://url,value1,value2
Run Code Online (Sandbox Code Playgroud)
第一行是标题,它也应该包含在csv中.今天我得到了一些有用的链接到stax,我真的不知道什么是正确的/最佳的方法,我现在正在努力3天,不是真的愿意放弃.
告诉我你的想法如何解决这个问题
我忘了提到这是一个非常庞大的xml文件,最高可达1GB
BOUNTY UPDATE:
我正在寻找更多的通用方法,这意味着这应该适用于任何数量的任何深度的节点,有时在例如xml中,可能会发生一个item对象具有比下一个/前一个更多的节点,所以那里也应该是这种情况(因此所有列和值都以CSV格式匹配).
此外,可能会发生节点具有相同名称/ localName但不同的值和属性,如果是这种情况,则新列应显示在具有适当值的CSV中.(我在<averages>标签里面添加了这个案例的例子category)
有点相关:来自java的libxml2
是的,这个问题相当啰嗦 - 对不起.我保持尽可能密集.我把问题加粗了,以便在阅读整篇文章之前更容易窥视.
为什么sax解析比dom解析更快? 我唯一能想到的是w/sax你可能忽略了大部分传入数据,因此不会浪费时间处理你不关心的xml部分.IOW - 解析w/SAX后,无法重新创建原始输入. 如果您编写SAX解析器以便它占据每个xml节点(并因此可以重新创建原始节点),那么它不会比DOM更快吗?
我问的原因是我正在尝试更快地解析xml文档.我需要在解析后访问整个xml树.我正在编写一个插入第三方服务的平台,所以我无法预测xml文档的哪些部分需要以及哪些部分不需要.我甚至不知道传入文件的结构.这就是为什么我不能使用jaxb或sax.内存占用对我来说不是问题,因为xml文档很小,我一次只需要1个内存.这是解析这个相对较小的xml文档所花费的时间.我之前没有使用过stax,但也许我需要进一步调查,因为它可能是中间地带? 如果我理解正确, 通过这种方式,原始的解析时间可能很快,但每次我要求它遍历尚未遍历的树的一部分时,就是处理发生的时候?
如果您提供了回答大多数问题的链接,我会接受您的回答(如果他们已在其他地方回答,您无需直接回答我的问题).
更新:我在sax中重写了它,并在avg 2.1 ms上解析文档.这比dom所采用的2.5毫秒有所改善(快16%),但这并不是我(等人)猜到的那么大.
谢谢
我用StAx编写了一个xml解析器,用于解析从服务器接收的XML流.这是我的代码:
private Map<String, IUnitaryAction> parse(InputStream is) throws XMLStreamException {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(is);
boolean action = false;
Map<String, IUnitaryAction> actionsMap = new HashMap<String, IUnitaryAction>();
while(reader.hasNext()){
int type = reader.next();
switch(type){
case XMLStreamReader.START_ELEMENT :
action = reader.getLocalName().equals("action-description");
break;
case XMLStreamReader.CHARACTERS :
if( action ){
String act = reader.getText();
System.out.println("Action trouvées " + act);
String[] praxiscmd = act.split("_");
if("CREATE".equals(praxiscmd[0])){
Create c = new Create(praxiscmd[1], praxiscmd[2], null);
actionsMap.put(praxiscmd[1], c);
} else if("DELETE".equals(praxiscmd[0])){
Delete d = new Delete(praxiscmd[1],praxiscmd[2], null);
actionsMap.put(praxiscmd[1], …Run Code Online (Sandbox Code Playgroud) 我需要阅读几个大的(200Mb-500Mb)XML文件,所以我想使用StaX.我的系统有两个模块 - 一个用于读取文件(使用StaX); 另一个模块('parser'模块)假设获取该XML的单个条目并使用DOM解析它.我的XML文件没有特定的结构 - 所以我不能使用JaxB.如何将"解析器"模块传递给我想要解析的特定条目?例如:
<Items>
<Item>
<name> .... </name>
<price> ... </price>
</Item>
<Item>
<name> .... </name>
<price> ... </price>
</Item>
</Items>
Run Code Online (Sandbox Code Playgroud)
我想使用StaX来解析该文件 - 但每个'item'条目都将传递给'parser'模块.
编辑:
经过多一点阅读 - 我想我需要一个使用流读取XML文件的库 - 但是使用DOM解析每个条目.有这样的事吗?
Is there a way I can use STAX parser to efficiently parse an XML document with multiple lists of objects of different classes (POJO). The exact structure of my XML is as follows (class names are not real)
<?xml version="1.0" encoding="utf-8"?>
<root>
<notes />
<category_alpha>
<list_a>
<class_a_object></class_a_object>
<class_a_object></class_a_object>
<class_a_object></class_a_object>
<class_a_object></class_a_object>
.
.
.
</list_a>
<list_b>
<class_b_object></class_b_object>
<class_b_object></class_b_object>
<class_b_object></class_b_object>
<class_b_object></class_b_object>
.
.
.
</list_b>
</category_alpha>
<category_beta>
<class_c_object></class_c_object>
<class_c_object></class_c_object>
<class_c_object></class_c_object>
<class_c_object></class_c_object>
<class_c_object></class_c_object>
.
.
.
.
.
</category_beta>
</root>
Run Code Online (Sandbox Code Playgroud)
I have been …
我没有看到一个选项javax.xml.stream.XMLEventWriter或javax.xml.stream.XMLOutputFactory以某种方式设置,以便写入空元素(而不是显式的开始和结束元素对).
我看到Woodstox有一个属性可以做到这一点,但它没有标准化.
我错过了任何明显的方法吗?
我第一次使用stax来解析XML String.我找到了一些例子,但无法让我的代码工作.这是我的代码的最新版本:
public class AddressResponseParser
{
private static final String STATUS = "status";
private static final String ADDRESS_ID = "address_id";
private static final String CIVIC_ADDRESS = "civic_address";
String status = null;
String addressId = null;
String civicAddress = null;
public static AddressResponse parseAddressResponse(String response)
{
try
{
byte[] byteArray = response.getBytes("UTF-8");
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray);
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader = inputFactory.createXMLStreamReader(inputStream);
while (reader.hasNext())
{
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT)
{
String element = reader.getLocalName(); …Run Code Online (Sandbox Code Playgroud) 输入文件包含数千个XML格式的事务,大小约为10GB.要求是根据用户输入选择每个事务XML并将其发送到处理系统.
文件的示例内容
<transactions>
<txn id="1">
<name> product 1</name>
<price>29.99</price>
</txn>
<txn id="2">
<name> product 2</name>
<price>59.59</price>
</txn>
</transactions>
Run Code Online (Sandbox Code Playgroud)
(技术)用户应该给出输入标签名称<txn>.
我们希望提供更通用的解决方案.文件内容可能不同,用户可以提供类似" //transactions/txn" 的XPath表达式来选择单个事务.
我们在这里需要考虑的技术问题很少
我们可以在这种情况下使用StAX解析器吗?它必须将XPath表达式作为输入和选择/选择事务XML.
寻找建议.提前致谢.
这是一个更为常见的问题:我使用的是xstream和woodstox,woodstox附带了一个服务提供程序,用于注册com.ctc.wstx.stax.WstxOutputFactory的woodstox jar中的javax.xml.stream.XMLOutputFactory.我想提供自己的javax.xml.stream.XMLOutputFactory,并且在类路径中仍然有woodstox jar.我知道我可以提供我自己的系统属性javax.xml.stream.XMLOutputFactory,但我正试图从我们的开发团队中解脱麻烦,并在我的jar中使用服务文件或者在我的战争中使用META -INF/services文件夹.查看javax.xml.stream.FactoryFinder的代码如何确保我的META-INF/services/javax.xml.stream.XMLOutputFactory文件将是FactoryFinder使用的文件?
我们使用xstream和camel,但找不到将工厂注入XStreamDataFormat的方法
我正在尝试使用Stax编写XML数据,其中内容本身是HTML
如果我试试
xtw.writeStartElement("contents");
xtw.writeCharacters("<b>here</b>");
xtw.writeEndElement();
Run Code Online (Sandbox Code Playgroud)
我明白了
<contents><b>here</b></contents>
Run Code Online (Sandbox Code Playgroud)
然后我注意到CDATA方法并将我的代码更改为:
xtw.writeStartElement("contents");
xtw.writeCData("<b>here</b>");
xtw.writeEndElement();
Run Code Online (Sandbox Code Playgroud)
这次结果是
<contents><![CDATA[<b>here</b>]]></contents>
Run Code Online (Sandbox Code Playgroud)
这仍然不好.我真正想要的是
<contents><b>here</b></contents>
Run Code Online (Sandbox Code Playgroud)
那么是否有一个XML API /库允许我在不加入CDATA部分的情况下编写原始文本?到目前为止,我已经看过Stax和JDom了,他们似乎没有提供这个.
最后我可能会选择好的旧StringBuilder,但这不会很优雅.
更新:
到目前为止,我主要同意答案.但是,<b>here</b>我可以将1MB HTML文档嵌入到更大的XML文档中.你的建议意味着我必须解析这个HTML文档才能理解它的结构.如果可能的话,我想避免这种情况.
回答:
这是不可能的,否则您可能会创建无效的XML文档.