如何使用在 SQL 中生成 XML 的 zBar

How to use zBar generated XML in SQL

我正在使用 zBar 从扫描的图像文件中读取 QR 码,但无法解析 zBar 在我的 SQL 脚本中生成的 XML。

作为背景,zBar 是一个开源的条码读取工具。除了在您自己的项目中使用的源代码外,还有一个命令行工具(zBarImg.exe)可以从图像文件中读取条形码(包括二维码)。我的 zBar 工作得很好,所以这个问题具体是关于如何使用它在我的 SQL 脚本中生成的 XML。

我正在使用 ZBar 命令行实用程序 (zbarimg) 读取每个图像上有两个二维码的图像,它会生成此 xml 文件:

<barcodes xmlns="http://zbar.sourceforge.net/2008/barcode">
  <source href="C:\BC\SCanner16_03_12_14_19_44.jpg">
    <index num="0">
      <symbol type="QR-Code" quality="1">
        <data>F01868</data>
      </symbol>
      <symbol type="QR-Code" quality="1">
        <data>TC16-A397</data>
      </symbol>
    </index>
  </source>
  <source href="C:\BC\SCanner16_03_12_14_19_46.jpg">
    <index num="0">
      <symbol type="QR-Code" quality="1">
        <data>F01869</data>
      </symbol>
      <symbol type="QR-Code" quality="1">
        <data>TC16-A397</data>
      </symbol>
    </index>
  </source>
  <source href="C:\BC\SCanner16_03_12_14_19_48.jpg">
    <index num="0">
      <symbol type="QR-Code" quality="1">
        <data>F01870</data>
      </symbol>
      <symbol type="QR-Code" quality="1">
        <data>TC16-A397</data>
      </symbol>
    </index>
  </source>
</barcodes>

效果很好,我可以看到我需要的所有信息。例如,在第一张图片上,我得到了文件名和两个二维码:

<source href="C:\BC\SCanner16_03_12_14_19_46.jpg">
<symbol type="QR-Code" quality="1"><data>F01868</data>
<symbol type="QR-Code" quality="1"><data>TC16-A397</data>

我无法将其解析/读入可用 table。

我认为我的问题是首先尝试获取一个元素,然后是节点...但我也很困惑,为什么它们的索引始终为零,而且它通常看起来是一种奇怪的构造 xml 的方式对我来说。

好的,所以我找到了一种方法来满足我的需求,所以我想分享它......并且看看社区是否可以提出更优雅的解决方案。

创建一个table并将xml拉入SQL。我实际上一次处理了很多 xml 个文件,所以在这里过于简单化了:

CREATE TABLE [dbo].[zBar_Batches](
        [ZBatchID] [int] IDENTITY(1,1) NOT NULL,
        [Filename] [nvarchar](255) NULL,
        [BarCodeXML] [xml] NULL,
        [Status] [nvarchar](50) NULL
        ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

        INSERT INTO zBar_Batches (Filename, BarCodeXML, Status) Values ('C:\BC\Logs\barcodes.xml', '', 'New Batch')
        UPDATE zBar_Batches SET BarCodeXML =(SELECT * FROM OPENROWSET(BULK 'C:\BC\Logs\barcodes.xml', SINGLE_BLOB ) AS x ) WHERE Filename = 'C:\BC\Logs\barcodes.xml'

让我挂了好几天的东西一直就在我眼前……我完全忘了设置默认的NAMESPACE。一旦我破解了它,事情就开始变得更好了。 我习惯于忽略 xml 文件的第一行,或者只看编码。我需要使用 XMLNAMESPACES(DEFAULT 'http://zbar.sourceforge.net/2008/barcode') 这是在这方面吸取的教训。

一旦我确定了这一点,我在 Stack Overflow 上所做的所有研究就开始发挥作用,我想出的最好的就是这个。我将是第一个承认交叉表 select 查询是由几个很棒的溢出线程拼凑而成的,因为这远远超出了我当时的能力范围。

IF OBJECT_ID('tempdb..#Pages') IS NOT NULL DROP TABLE #Pages
    CREATE TABLE #Pages(
        [zbarID] [int] IDENTITY(1,1) NOT NULL,
        [FilePath] [varchar](255) NULL,
        [QRcode] [varchar](50) NULL
    )

DECLARE @zXML xml

SELECT @zXML = BarCodeXML from zBar_Batches where ZBatchID= @BatchID and BarCodeXML is not null
;WITH XMLNAMESPACES(DEFAULT 'http://zbar.sourceforge.net/2008/barcode') 
INSERT INTO #Pages
select batch.src.value('@href','varchar(255)') as FilePath,
    batch1.sym.value('data[1]','varchar(50)') as QRcode
    from @zXML.nodes('/barcodes/source') as batch(src)
    cross apply batch.src.nodes('index/symbol') as batch1(sym)

这给了我六行...每个条形码一行(3 个图像中的每一个 2)。

zbarID  FilePath                                QRcode
------- --------------------------------------- -----------
1       C:\BC\SCanner16_03_12_14_19_44.jpg   F01868
2       C:\BC\SCanner16_03_12_14_19_44.jpg   TC16-A397
3       C:\BC\SCanner16_03_12_14_19_46.jpg   F01869
4       C:\BC\SCanner16_03_12_14_19_46.jpg   TC16-A397
5       C:\BC\SCanner16_03_12_14_19_48.jpg   F01870
6       C:\BC\SCanner16_03_12_14_19_48.jpg   TC16-A397

当然我还有一些验证工作要做,需要依靠二维码值的格式来知道它是哪个代码,但很快就完成了,

我希望这可以帮助任何其他尝试将 zBar xml 与 sql 一起使用的人。我希望看到有关最终查询的任何反馈。

如果您有兴趣,zBar 还有一个命令行可以从连接到计算机的网络摄像头读取。 zBarImg 实用程序对我来说效果很好。在我使用它处理的近 1500 张图像中,它能够准确读取 98% 的二维码。