XQuery:返回一个空元素,而不是带有数据的元素

时间:2017-09-07 06:47:16

标签: xml xquery

我有一个XML文档(catalog.xml),如下所示

<catalog>
 <product dept="WMN">
  <number>557</number>
  <name language="en">Fleece_Pullover</name>
  <colorChoices>navy black</colorChoices>
 </product>
 <product dept="ACC">
  <number>563</number>
  <name language="en">Floppy_Sun_Hat</name>
 </product>
 <product dept="ACC">
   <number>443</number>
   <name language="en">Deluxe_Travel_Bag</name>
 </product>
 <product dept="MEN">
  <number>784</number>
  <name language="en">Cotton_Dress_Shirt</name>
  <colorChoices>white gray</colorChoices>
  <desc>Our <i>favorite</i> shirt!</desc>
 </product>
</catalog>

当我评估时

doc("catalog.xml")//product 

我得到的结果为:

<product dept="WMN">
 <number>557</number>
 <name language="en">Fleece_Pullover</name>
 <colorChoices>navy black</colorChoices>
</product>
<product dept="ACC">
 <number>563</number>
 <name language="en">Floppy_Sun_Hat</name>
</product>
<product dept="ACC">
 <number>443</number>
 <name language="en">Deluxe_Travel_Bag</name>
</product>
<product dept="MEN">
 <number>784</number>
 <name language="en">Cotton_Dress_Shirt</name>
 <colorChoices>white gray</colorChoices>
 <desc>Our<i>favorite</i>shirt!</desc>
</product>

我们要求从xml读取数据,文件大小可能超过1GB。我们只需要显示具有其属性的节点,但不需要内部数据。

有没有办法只获得如下标签。

<product dept="WMN"/>
<product dept="ACC"/>
<product dept="ACC"/>
<product dept="MEN"/>

2 个答案:

答案 0 :(得分:1)

使用XQuery,您只需构造一个product元素并返回dept属性的值。

    Sub a()

Dim lastrow3 As Long

    Sheets.Add.Name = "Report_Copy"
    Worksheets("Report").Cells.Copy
    With Worksheets("Report_Copy")
    .Cells.PasteSpecial xlValues
    .Cells.PasteSpecial xlFormats
    End With
    With Worksheets("Report_Copy").UsedRange
        .Value = .Value
    End With

    Dim i As Long

With Sheets("Report_Copy")
    lastrow3 = .Cells(.Rows.Count, "K").End(xlUp).Row

    For i = lastrow3 To 25 Step -1
        Set cell = .Range("L" & i)
        If WorksheetFunction.CountIf(.Range(cell, cell.Offset(0, 9)), "<0.5") = 10 Then
            cell.EntireRow.Delete
        End If
    Next i
End With

End Sub

答案 1 :(得分:1)

从功能上讲,这很容易,如@chrisis所示。问题是此解决方案是否适用于1Gb输入文档,这取决于实现。许多实现(如果输入是文件存储中的原始XML而不是数据库)将尝试在内存中构建树,这可能需要高达10Gb的内存,具体取决于树表示的紧凑程度。真的,你需要一个流媒体解决方案。

XSLT 3.0已经在规范中构建了流式传输,您可以使用代码

获得有保证的流式传输
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>

<xsl:template match="product">
  <product dept="{@dept}"/>
</xsl:template>
</xsl:transform>

是否可以让XQuery产品使用流式传输完全取决于产品,因为W3C规范在此问题上无话可说。例如,Saxon在XQuery中确实具有一些流媒体功能,但它们依赖于规范的供应商扩展。