[英]XML to CSV with BaseX/XQuery
我正在嘗試將大量 xml 轉換為單個 csv 文件。 xml 的簡化結構如下所示:
<Receipts>
<Receipt>
<Field1 attribute1="a"/>
<Fields2>
<Field2 attribute2="1"/>
<Field2 attribute2="2"/>
</Fields2>
<Field4 attribute4="4a"/>
</Receipt>
<Receipt>
<Field1 attribute1="b"/>
<Field4 attribute4="4b"/>
</Receipt>
<Receipt>
<Field1 attribute1="c"/>
<Fields2>
<Field2 attribute2="3"/>
</Fields2>
<Field3 attribute3="c3"/>
<Field4 attribute4="4c"/>
</Receipt>
</Receipts>
我想獲得的 csv 結果是
Attribute1,Attribute2,Attribute3,Attribute4
a,1,,4a
a,2,,4a
b,,,4b
c,3,c3,4c
我的代碼基於這個答案,但我只能在 csv 上為每個連接了所有屬性 2 的收據創建一行,或者只返回具有 Fields2 元素和 Field2 的收據,即:要么:
Attribute1,Attribute2,Attribute3,Attribute4
a,1 2,,4a
b,,,4b
c,3,c3,4c
或這個:
Attribute1,Attribute2,Attribute3,Attribute4
a,1,,4a
a,2,,4a
c,3,c3,4c
我的第一種情況的代碼是:
declare option output:method "csv";
declare option output:csv "header=yes, separator=comma";
declare context item := document {<Receipts>
<Receipt>
<Field1 attribute1="a"/>
<Fields2>
<Field2 attribute2="1"/>
<Field2 attribute2="2"/>
</Fields2>
<Field4 attribute4="4a"/>
</Receipt>
<Receipt>
<Field1 attribute1="b"/>
<Field4 attribute4="4b"/>
</Receipt>
<Receipt>
<Field1 attribute1="c"/>
<Fields2>
<Field2 attribute2="3"/>
</Fields2>
<Field3 attribute3="c3"/>
<Field4 attribute4="4c"/>
</Receipt>
</Receipts>};
for $x in //Receipt
return
<csv>
<record>
<Attribute1>{$x/Field1/@attribute1/data()}</Attribute1>
<Attribute2>{$x/Fields2/Field2/@attribute2/data()}</Attribute2>
<Attribute3>{$x/Field3/@attribute3/data()}</Attribute3>
<Attribute4>{$x/Field4/@attribute4/data()}</Attribute4>
</record>
</csv>
對於第二種情況,它將是:
declare option output:method "csv";
declare option output:csv "header=yes, separator=comma";
declare context item := document {<Receipts>
<Receipt>
<Field1 attribute1="a"/>
<Fields2>
<Field2 attribute2="1"/>
<Field2 attribute2="2"/>
</Fields2>
<Field4 attribute4="4a"/>
</Receipt>
<Receipt>
<Field1 attribute1="b"/>
<Field4 attribute4="4b"/>
</Receipt>
<Receipt>
<Field1 attribute1="c"/>
<Fields2>
<Field2 attribute2="3"/>
</Fields2>
<Field3 attribute3="c3"/>
<Field4 attribute4="4c"/>
</Receipt>
</Receipts>};
for $x in //Receipt for $y in $x/Fields2/Field2
return
<csv>
<record>
<Attribute1>{$x/Field1/@attribute1/data()}</Attribute1>
<Attribute2>{$y/@attribute2/data()}</Attribute2>
<Attribute3>{$x/Field3/@attribute3/data()}</Attribute3>
<Attribute4>{$x/Field4/@attribute4/data()}</Attribute4>
</record>
</csv>
經過更深入的搜索,我找到了解決方案。 在第二個 for 循環的第二個選項上,您應該添加allowing empty
的 function,以便代碼最終看起來像這樣:
declare option output:method "csv";
declare option output:csv "header=yes, separator=comma";
declare context item := document {<Receipts>
<Receipt>
<Field1 attribute1="a"/>
<Fields2>
<Field2 attribute2="1"/>
<Field2 attribute2="2"/>
</Fields2>
<Field4 attribute4="4a"/>
</Receipt>
<Receipt>
<Field1 attribute1="b"/>
<Field4 attribute4="4b"/>
</Receipt>
<Receipt>
<Field1 attribute1="c"/>
<Fields2>
<Field2 attribute2="3"/>
</Fields2>
<Field3 attribute3="c3"/>
<Field4 attribute4="4c"/>
</Receipt>
</Receipts>};
for $x in //Receipt for $y allowing empty in $x/Fields2/Field2
return
<csv>
<record>
<Attribute1>{$x/Field1/@attribute1/data()}</Attribute1>
<Attribute2>{$y/@attribute2/data()}</Attribute2>
<Attribute3>{$x/Field3/@attribute3/data()}</Attribute3>
<Attribute4>{$x/Field4/@attribute4/data()}</Attribute4>
</record>
</csv>
返回設計者 CSV:
Attribute1,Attribute2,Attribute3,Attribute4
a,1,,4a
a,2,,4a
b,,,4b
c,3,c3,4c
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.