2016-06-29 8 views
0

У меня есть требование, когда мне нужно выводить необязательные элементы XML всегда (независимо от доступности данных) при записи в CSV-файл.Как выводить некоторые необязательные элементы XML/узлы, всегда используя XQUERY

Формат файла XML

<entries> 
    <countryCode>123</countryCode> 
    <adminDataMap> 
    <testAccount>True</testAccount> 
    <code>11</code> 
    </adminDataMap> 
    <privateMap> 
    <email>[email protected]</email> 
    <cancelReason>Not interested</cancelReason> 
    </privateMap> 
</entries> 

Вот записей 'Корневой элемент «cancelReason», «акаонт» являются необязательными элементами, которые будут доступны только один раз данные есть.

i.e Некоторые записи будут иметь эти «необязательные» поля, а другие нет.

Я написал XQuery, чтобы извлечь все эти элементы

let $entries := /root/entries 
return 
    for $entry in $entries 
    return 
    <entries> 
    { 
     $entry/*, 
     $entry/privateMap/email, 
     $entry/privateMap/cancelReason, 
     $entry/adminDataMap/code, 
     $entry/adminDataMap/testAccount 
    } 
    </entries> 

Мое требование, чтобы извлечь все обязательные и дополнительные элементы, как OUTPUT. i.e Метаданные вывода всегда остаются такими же. Если опция «cancelReason» не имеет значения, она будет заполнена как пробелы/нули [что-то вроде этого]

Просьба сообщить любые варианты в XQUERY, которые могут быть написаны для этого.

ответ

0

Попробуйте XQUERY:

let $entries := $root/entries 

for $entry in $entries

return <OUTPUT> 
{<mandatory>{$entry//countryCode} 
{<adminDataMap>{$entry//adminDataMap/code}</adminDataMap>} 
{$entry//privateMap/email}</mandatory>} 
{<optional>{<testAccount>{data($entry/adminDataMap/testAccount)}</testAccount>} 
<cancelReason>{data($entry/privateMap/cancelReason)}</cancelReason></optional> 
}</OUTPUT> 

, что дает обязательные и необязательные элементы отдельно для каждой записи.

0

Попробуйте XQuery:

for $entry in $entries 
return 
    <entries> 
    { 
     for $admin in $entry/adminDataMap 
     return 
      <admin> 
       {$admin/code} 
       <testAccount>{data($admin/testAccount)}</testAccount> 
      </admin>, 

     for $private in $entry/privateMap 
     return 
      <private> 
       {$private/email} 
       <cancelReason>{data($private/cancelReason)}</cancelReason> 
      </private> 
    } 
    </entries> 

Это даст вам пустые элементы отсутствуют необязательные элементы.


Ну, попробуйте это

return 
    <entries> 
    { 
     for $admin in $entries/adminDataMap 
     return 
      <admin> 
       {$admin/code} 
       <testAccount>{data($admin/testAccount)}</testAccount> 
      </admin>, 

     for $private in $entries/privateMap 
     return 
      <private> 
       {$private/email} 
       <cancelReason>{data($private/cancelReason)}</cancelReason> 
      </private> 
    } 
    </entries> 

я тестировал оба метода на Basex и SqlServer - оба работают.


Я думаю, все зависит от того, как вы устанавливаете начальное значение.
Я вижу root в вашем коде:

let $entries := /root/entries 

Между тем, в XML нет элемента с именем root.

Этот код работает, если значение устанавливается следующим образом:

let $entries := 
<entries> 
    <!-- ... --> 
</entries> 
+0

Я попробовал ваш подход. Я видел, что когда я выполняю все три цикла FOR (с переменными «entry», «admin», «private»), только элементы/поля, определенные с помощью цикла «entry», получают выход. другие 2 цикла «admin», «private» игнорируются. Однако, когда я пробовал «админ», «частный» цикл FOR отдельно, он работает как шарм. Возможно, я ошибаюсь в синтаксисе. Не уверен. Пожалуйста, порекомендуйте. –

+0

@TomGeorge - см. Обновление. –

+0

Это работает. !! Спасибо за ваши ценные материалы. –