在 BaseX 中将 xml 从 XQuery 转换为 csv
Converting xml to csv from XQuery in BaseX
我写这篇文章的原因是因为我在 BaseX 中有一个包含大约 1k xml 的数据库。我已经清理了它并获得了我想要的信息。不过,我希望能够以 CSV 格式导出该数据。当我尝试使用 BaseX 文档中给出的代码时,它给了我这个:
Desc,Cantidad,Valor,Fecha,Lugar,UUID
,,,,,
,,,,,
它应该显示逗号之间的数据。
我想问的是我应该如何修改我的代码才能显示数据。
我的代码如下:
declare namespace tfd="http://www.sat.gob.mx/TimbreFiscalDigital";
declare namespace cfdi= "http://www.sat.gob.mx/cfd/3";
declare option output:method "csv";
declare option output:csv "header=yes, separator=comma";
declare context item := document {
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:detallista="http://www.sat.gob.mx/detallista" xmlns:psgecfd="http://www.sat.gob.mx/psgecfd" xmlns:ecc="http://www.sat.gob.mx/ecc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" folio="131556" fecha="2014-07-01T08:13:34" noCertificado="00001000000301092647" formaDePago="Pago en una sola exhibicion" subTotal="156.8966" descuento="0.00" Moneda="NAL" total="182.00" tipoDeComprobante="ingreso" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd http://www.posadas.com/MFE http://www.posadas.com/MFE/ADDENDAPOSADASVL1.xsd" xmlns:posadas="http://www.posadas.com/MFE" metodoDePago="TARJETA DE CREDITO" NumCtaPago="1093" LugarExpedicion="AVENIDA COSTERA MIGUEL ALEMAN ACAPULCO DE JUAREZ GUERRERO MEXICO">
<cfdi:Emisor rfc="ASO0408178B2" nombre="HOTELES Y VILLAS POSADAS, S.A. DE C.V.">
<cfdi:DomicilioFiscal calle="AVENIDA PASEO DE LA REFORMA" noExterior="155" noInterior="PISO 4" colonia="LOMAS DE CHAPULTEPEC I SECCION" municipio="MIGUEL HIDALGO" estado="DISTRITO FEDERAL" pais="MEXICO" codigoPostal="11000"/>
<cfdi:ExpedidoEn calle="AVENIDA COSTERA MIGUEL ALEMAN" noExterior="97" colonia="FRACCIONAMIENTO CLUB DEPORTIVO" municipio="ACAPULCO DE JUAREZ" pais="MEXICO" codigoPostal="39690" estado="GUERRERO"/>
<cfdi:RegimenFiscal Regimen="NA"/>
</cfdi:Emisor>
<cfdi:Receptor rfc="MER551201D48" nombre="MERCK SA DE CV">
<cfdi:Domicilio calle="CALLE 5 No. 7 FRACC. ALCE BLANCO" municipio="NAUCALPAN DE JUAREZ" estado="ESTADO DE MEXICO" pais="MX" codigoPostal="53370"/>
</cfdi:Receptor>
<cfdi:Conceptos>
<cfdi:Concepto cantidad="1.00" unidad="SERVICIO" noIdentificacion="CONSUM" descripcion="CONSUMO" valorUnitario="156.8966" importe="156.8966"/>
</cfdi:Conceptos>
<cfdi:Impuestos totalImpuestosTrasladados="25.1034">
<cfdi:Traslados>
<cfdi:Traslado tasa="16.00" importe="25.1034" impuesto="IVA"/>
</cfdi:Traslados>
</cfdi:Impuestos> <cfdi:Complemento>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd" FechaTimbrado="2014-07-01T08:15:15" UUID="8a4f1be7-bdcb-4b22-b144-b3e41dd92e69" version="1.0"/>
</cfdi:Complemento>
<cfdi:Addenda>
<posadas:RequestForPayment>
<posadas:Hoteleria cajero="210" folio="539809" importeaPagar=" 200.00" propina=" 18.00" >
</posadas:Hoteleria>
</posadas:RequestForPayment>
</cfdi:Addenda>
</cfdi:Comprobante>};
for $x in //cfdi:Comprobante,
$y in $x//cfdi:Conceptos/cfdi:Concepto,
$z in $x//cfdi:Complemento/tfd:TimbreFiscalDigital,
$w in $x//cfdi:ExpedidoEn
return
<csv>
<Desc>{$y/@descripcion}</Desc>
<Cantidad>{$y/@cantidad}</Cantidad>
<Valor>{$y/@valorUnitario}</Valor>
<Fecha>{$z/@FechaTimbrado}</Fecha>
<Lugar>{$w/@codigoPostal}</Lugar>
<UUID>{$z/@UUID}</UUID>
</csv>
CSV 序列化所需的 XML 在 CSV module 文档中进行了描述。 BaseX 文档中的示例:
<csv>
<record>
<Name>Huber</Name>
<First_Name>Sepp</First_Name>
<Address>Hauptstraße 13</Address>
<City>93547 Hintertupfing</City>
</record>
</csv>
换句话说,<csv/>
元素包装所有数据,每条记录由 <csv/>
元素分隔,最后列存储为带有文本节点子元素的元素。
查看当前输出(通过删除序列化选项),返回以下内容:
<csv>
<Desc descripcion="CONSUMO"/>
<Cantidad cantidad="1.00"/>
<Valor valorUnitario="156.8966"/>
<Fecha FechaTimbrado="2014-07-01T08:15:15"/>
<Lugar codigoPostal="39690"/>
<UUID UUID="8a4f1be7-bdcb-4b22-b144-b3e41dd92e69"/>
</csv>
您有两种情况不符合要求:
- 没有
<record/>
个元素
- 值存储为属性,而不是文本节点
如果您使用如下查询更正这两个问题:
for $x in //cfdi:Comprobante,
$y in $x//cfdi:Conceptos/cfdi:Concepto,
$z in $x//cfdi:Complemento/tfd:TimbreFiscalDigital,
$w in $x//cfdi:ExpedidoEn
return
<csv><record>
<Desc>{$y/@descripcion/data()}</Desc>
<Cantidad>{$y/@cantidad/data()}</Cantidad>
<Valor>{$y/@valorUnitario/data()}</Valor>
<Fecha>{$z/@FechaTimbrado/data()}</Fecha>
<Lugar>{$w/@codigoPostal/data()}</Lugar>
<UUID>{$z/@UUID/data()}</UUID></record>
</csv>
您得到预期的 CSV 输出:
Desc,Cantidad,Valor,Fecha,Lugar,UUID
CONSUMO,1.00,156.8966,2014-07-01T08:15:15,39690,8a4f1be7-bdcb-4b22-b144-b3e41dd92e69
在编辑器中打开文件并将所有 <\ 替换为 ;<\
接下来在 BaseX 中打开文件并导出为 csv
我写这篇文章的原因是因为我在 BaseX 中有一个包含大约 1k xml 的数据库。我已经清理了它并获得了我想要的信息。不过,我希望能够以 CSV 格式导出该数据。当我尝试使用 BaseX 文档中给出的代码时,它给了我这个:
Desc,Cantidad,Valor,Fecha,Lugar,UUID
,,,,,
,,,,,
它应该显示逗号之间的数据。 我想问的是我应该如何修改我的代码才能显示数据。
我的代码如下:
declare namespace tfd="http://www.sat.gob.mx/TimbreFiscalDigital";
declare namespace cfdi= "http://www.sat.gob.mx/cfd/3";
declare option output:method "csv";
declare option output:csv "header=yes, separator=comma";
declare context item := document {
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:detallista="http://www.sat.gob.mx/detallista" xmlns:psgecfd="http://www.sat.gob.mx/psgecfd" xmlns:ecc="http://www.sat.gob.mx/ecc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" folio="131556" fecha="2014-07-01T08:13:34" noCertificado="00001000000301092647" formaDePago="Pago en una sola exhibicion" subTotal="156.8966" descuento="0.00" Moneda="NAL" total="182.00" tipoDeComprobante="ingreso" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd http://www.posadas.com/MFE http://www.posadas.com/MFE/ADDENDAPOSADASVL1.xsd" xmlns:posadas="http://www.posadas.com/MFE" metodoDePago="TARJETA DE CREDITO" NumCtaPago="1093" LugarExpedicion="AVENIDA COSTERA MIGUEL ALEMAN ACAPULCO DE JUAREZ GUERRERO MEXICO">
<cfdi:Emisor rfc="ASO0408178B2" nombre="HOTELES Y VILLAS POSADAS, S.A. DE C.V.">
<cfdi:DomicilioFiscal calle="AVENIDA PASEO DE LA REFORMA" noExterior="155" noInterior="PISO 4" colonia="LOMAS DE CHAPULTEPEC I SECCION" municipio="MIGUEL HIDALGO" estado="DISTRITO FEDERAL" pais="MEXICO" codigoPostal="11000"/>
<cfdi:ExpedidoEn calle="AVENIDA COSTERA MIGUEL ALEMAN" noExterior="97" colonia="FRACCIONAMIENTO CLUB DEPORTIVO" municipio="ACAPULCO DE JUAREZ" pais="MEXICO" codigoPostal="39690" estado="GUERRERO"/>
<cfdi:RegimenFiscal Regimen="NA"/>
</cfdi:Emisor>
<cfdi:Receptor rfc="MER551201D48" nombre="MERCK SA DE CV">
<cfdi:Domicilio calle="CALLE 5 No. 7 FRACC. ALCE BLANCO" municipio="NAUCALPAN DE JUAREZ" estado="ESTADO DE MEXICO" pais="MX" codigoPostal="53370"/>
</cfdi:Receptor>
<cfdi:Conceptos>
<cfdi:Concepto cantidad="1.00" unidad="SERVICIO" noIdentificacion="CONSUM" descripcion="CONSUMO" valorUnitario="156.8966" importe="156.8966"/>
</cfdi:Conceptos>
<cfdi:Impuestos totalImpuestosTrasladados="25.1034">
<cfdi:Traslados>
<cfdi:Traslado tasa="16.00" importe="25.1034" impuesto="IVA"/>
</cfdi:Traslados>
</cfdi:Impuestos> <cfdi:Complemento>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd" FechaTimbrado="2014-07-01T08:15:15" UUID="8a4f1be7-bdcb-4b22-b144-b3e41dd92e69" version="1.0"/>
</cfdi:Complemento>
<cfdi:Addenda>
<posadas:RequestForPayment>
<posadas:Hoteleria cajero="210" folio="539809" importeaPagar=" 200.00" propina=" 18.00" >
</posadas:Hoteleria>
</posadas:RequestForPayment>
</cfdi:Addenda>
</cfdi:Comprobante>};
for $x in //cfdi:Comprobante,
$y in $x//cfdi:Conceptos/cfdi:Concepto,
$z in $x//cfdi:Complemento/tfd:TimbreFiscalDigital,
$w in $x//cfdi:ExpedidoEn
return
<csv>
<Desc>{$y/@descripcion}</Desc>
<Cantidad>{$y/@cantidad}</Cantidad>
<Valor>{$y/@valorUnitario}</Valor>
<Fecha>{$z/@FechaTimbrado}</Fecha>
<Lugar>{$w/@codigoPostal}</Lugar>
<UUID>{$z/@UUID}</UUID>
</csv>
CSV 序列化所需的 XML 在 CSV module 文档中进行了描述。 BaseX 文档中的示例:
<csv>
<record>
<Name>Huber</Name>
<First_Name>Sepp</First_Name>
<Address>Hauptstraße 13</Address>
<City>93547 Hintertupfing</City>
</record>
</csv>
换句话说,<csv/>
元素包装所有数据,每条记录由 <csv/>
元素分隔,最后列存储为带有文本节点子元素的元素。
查看当前输出(通过删除序列化选项),返回以下内容:
<csv>
<Desc descripcion="CONSUMO"/>
<Cantidad cantidad="1.00"/>
<Valor valorUnitario="156.8966"/>
<Fecha FechaTimbrado="2014-07-01T08:15:15"/>
<Lugar codigoPostal="39690"/>
<UUID UUID="8a4f1be7-bdcb-4b22-b144-b3e41dd92e69"/>
</csv>
您有两种情况不符合要求:
- 没有
<record/>
个元素 - 值存储为属性,而不是文本节点
如果您使用如下查询更正这两个问题:
for $x in //cfdi:Comprobante,
$y in $x//cfdi:Conceptos/cfdi:Concepto,
$z in $x//cfdi:Complemento/tfd:TimbreFiscalDigital,
$w in $x//cfdi:ExpedidoEn
return
<csv><record>
<Desc>{$y/@descripcion/data()}</Desc>
<Cantidad>{$y/@cantidad/data()}</Cantidad>
<Valor>{$y/@valorUnitario/data()}</Valor>
<Fecha>{$z/@FechaTimbrado/data()}</Fecha>
<Lugar>{$w/@codigoPostal/data()}</Lugar>
<UUID>{$z/@UUID/data()}</UUID></record>
</csv>
您得到预期的 CSV 输出:
Desc,Cantidad,Valor,Fecha,Lugar,UUID
CONSUMO,1.00,156.8966,2014-07-01T08:15:15,39690,8a4f1be7-bdcb-4b22-b144-b3e41dd92e69
在编辑器中打开文件并将所有 <\ 替换为 ;<\
接下来在 BaseX 中打开文件并导出为 csv