我有以下xml doc:
<database>
<order>
<data>
<field name="time" value="10:10:10" />
</data>
<data>
<field name="product" value="product_type_1">
<field name="attributeA" value="Foo" />
<field name="attributeB" value="Bar" />
</field>
<field name="attributeC" value="Jeam" />
<field name="attributeD" value="Beam" />
<field name="attributeE" value="Deam" />
</data>
</order>
<order>
<data>
<field name="time" value="10:10:11" />
</data>
<data>
<field name="product" value="product_type_2">
<field name="attributeF" value="Bravo" />
<field name="attributeG" value="Echo" />
</field>
<field name="attributeC" value="Jeam2" />
<field name="attributeD" value="Beam2" />
<field name="attributeJ" value="Charlie" />
<field name="attributeK" value="Tango" />
<field name="attributeL" value="Zulu" />
</data>
</order>
它是一组“order”元素,但“field”(数量和类型)取决于名称为“product”的元素的值。我有兴趣根据产品的价值提取信息。更具体地说,我最终会得到类似这样的表格:
Time Product AttributeA AttributeB AttributeC AttributeD
10:10:10 product_type_1 Foo Bar Jeam Beam
10:10:11 product_type_2 Jeam2 Beam2
换句话说,我试图根据“订单”的子元素的值“削减”不必要的信息。我试图通过使用xpath(在java中)实现这一点,但我被卡住了。我不可能模仿上面描述的“if”条件。
我正在考虑使用和xpath查询一次检索一个订单元素,然后查询产品类型,然后选择适当的xpath来解除相应的属性,但这听起来确实有效且缓慢。
是否可以更有效地完成它? xpath不是正确答案吗?
提前致谢。
P.S:只要我检索到正确的数据,您在上面看到的数据的对齐和组织并不重要,那么我相信我能够以某种方式打印它们。
答案 0 :(得分:1)
如果你想使用XPath,你至少需要XPath 3.0或XQuery(这个代码在这两个代码中都有效)。如果你想在Java中使用它,请查看XQuery引擎,例如Saxon,BaseX,eXist DB,......
for $order in /database/order
return string-join((
$order//field[@name='time']/@value,
$order//field[@name='product']/@value,
($order//field[@name='attributeA']/@value, '')[1],
($order//field[@name='attributeB']/@value, '')[1],
($order//field[@name='attributeC']/@value, '')[1],
($order//field[@name='attributeD']/@value, '')[1]),
'	')
用于属性的模式确保空值不会破坏表格布局(因此对于第二种产品类型,属性C和D不会获取属性A和B)。 	
是制表符。
如果你想使用Java来进一步处理输出,我会接受这个:获取所有订单(/database/order
)并循环它们。然后,对于每个订单,使用DOM(或再次使用XPath)来获取所需的节点。然而,您提出的问题似乎不是您的实际问题,可能是使用XQuery可能会带来更清晰的解决方案。