我有一个大型的xml文件,其中有很多编组过的表格,如下所示:
<!-- language: lang-xml -->
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE package SYSTEM "http://www.f.ru/NSI/dtds/package.dtd">
<package>
<rollout dateSet="2016.01.01" name="deposit.PSBD.IN.04" timeSet="11:47" version="1">
<comment>88766</comment>
<transaction group="1" name="name">
<comment/>
<table name="T_NAME">
<comment/>
<tabledesc>
<fielddesc name="T_TYP" key="true" type="numeric" length="10" nullable="false" label="" comment=""/>
<fielddesc name="T_NMB" key="false" type="string" length="40" nullable="false" label="" comment=""/>
<fielddesc name="T_AUD" key="false" type="string" length="1" nullable="false" label="" comment=""/>
</tabledesc>
<convert/>
<replace>
<record>
<field name="T_TYP" null="false" value="0"/>
<field name="T_NMB" null="false" value="qwe"/>
<field name="T_AUD" null="false" value="1"/>
</record>
<record>
<field name="T_TYP" null="false" value="1"/>
<field name="T_NMB" null="false" value="qwer"/>
<field name="T_AUD" null="false" value="1"/>
</record>
<record>
<field name="T_TYP" null="false" value="2"/>
<field name="T_NMB" null="false" value="qwert"/>
<field name="T_AUD" null="false" value="1"/>
</record>
</replace>
</table>
</transaction>
</rollout>
</package>
现在,我需要在一个名为=&#34; T_NAME&#34;的表格中统计记录。我没有任何模式,我也不需要解组这个表(这是下一步)。 JAXB是一个简单的sax-parsing机制,只是用于搜索吗?
答案 0 :(得分:0)
如果在进行任何解组之前需要计算,那么您将不再需要JAXB。 JAXB旨在将XML绑定到Java对象。对于这样的任务,您可以使用解析器(StAX流API将是一个不错的选择),但更容易使用XSLT转换。它不需要任何其他依赖项,只需使用Java中的XML转换API。
一个样式表,用于计算表中具有特定名称的所有<record>
元素:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*" />
</xsl:template>
<xsl:template match="table[@name='T_NAME']">
<xsl:value-of select="count(.//record)" />
</xsl:template>
</xsl:stylesheet>
查看javax.xml.transform包。默认情况下,Java运行时附带一个XSLT 1.0转换器(基于Apache Xalan)。获得变压器的切入点是TransformerFactory class。可以在网上找到这些教程。
通过提供表名作为参数,可以使样式表更灵活:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:param name="tableName" select="'T_NAME'" />
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*" />
</xsl:template>
<xsl:template match="table[@name=$tableName]">
<xsl:value-of select="count(.//record)" />
</xsl:template>
</xsl:stylesheet>
然后可以使用方法setParameter on a Transformer提供参数值。如果代码没有给出样式表中的值,则它将作为默认值。
通过一些实验,您可以按名称输出每个表的记录计数的文件,如下所示:
T_NAME=3
T_OTHER=4
...
如果必须为多个表执行此操作,可能会有用。 Java中的XSLT速度非常快,内存使用率也不错,特别是对于像这样的简单样式表。