2013-11-24 2 views
0

У меня есть следующий XML-документ:Получение значений атрибутов в зависимости от значения другого атрибута с помощью XPath

<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> 

Это представляет собой набор элементов «порядок», но «поле» (как на количество и тип) зависят от значения элемента, имя которого является «продуктом». Меня интересует извлечение информации в зависимости от ценности продукта. Более конкретно, я бы в конечном итоге с чем-то вроде этой таблицы:

Time  Product   AttributeA AttributeB AttributeC AttributeD 
10:10:10 product_type_1 Foo  Bar  Jeam  Beam 
10:10:11 product_type_2       Jeam2  Beam2 

Другими словами я пытаюсь «вырезать» unesessary информацию в зависимости от значения дочернего элемента «порядка». Я пытаюсь добиться этого, используя xpath (в java), но я застрял. Я не могу подражать описанному выше условию «если».

Я собираюсь использовать и запрос xpath для извлечения одного элемента заказа за раз, затем запросить тип продукта, а затем выбрать подходящий xpath для извлечения соответствующих атрибутов, но это звучит очень мало и медленно.

Возможно ли это сделать более эффективно? Является ли xpath неправильным ответом здесь?

Заранее спасибо.

P.S: Выравнивание и организация данных, которые вы видите выше, на самом деле не имеют значения до тех пор, пока я получаю правильные данные, тогда я уверен, что смогу их распечатать каким-то образом.

ответ

1

Если вы хотите использовать XPath, вам понадобится хотя бы XPath 3.0 или XQuery (этот код действителен в обоих из них). Посмотрите на двигатели XQuery, если вы хотите использовать это в Java, например, 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]), 
    '&#9;') 

Шаблон используется для атрибутов убеждается, что пустые значения не нарушают таблицу (так что для второго типа продукта атрибуты C и D не получают атрибуты A и B). &#9; - символ табуляции.


Если вы хотите использовать Java для дальнейшей обработки на выходе, я бы с этим: Fetch все заказы (/database/order) и петлю над ними. Затем для каждого заказа снова используйте DOM (или XPath) для получения нужных вам узлов. Тем не менее, кажется, что заданный вами вопрос не является вашей фактической проблемой, возможно, использование XQuery может привести к более чистым решениям.

+0

Из-за моих ограниченных знаний о XPath мне показалось, что XPath будет работать как волшебная палочка для моей проблемы. Вскоре стало очевидно, что XPath не является ответом. XQuery может иметь кривую обучения, поэтому я фокусирую XPath с DOM, как предложил Йенс Эрат. У меня возникли проблемы со средними большими (~ 1 гб) размером xml-файлы в вопросах памяти, но я изучаю и пытаюсь опубликовать решение здесь. –

+0

Возможно, вы захотите посмотреть на базы данных XML, такие как BaseX, Sedna и eXist, тогда у вас не должно быть проблем с основной памятью. XQuery определенно имеет крутую кривую обучения, если вы не привыкли к функциональному программированию, но стоит усилий. В BaseX есть некоторые хорошие инструменты визуализации, которые могут помочь вам при изучении XQuery и довольно легко настроить. _ (Отказ от ответственности: я несколько связан с командой BaseX.) _ –

Смежные вопросы