I have a large xml file with a lot of marshalled tables structured like this:
<!-- 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>
And NOW I need to count records in one table with name="T_NAME". I do not have any schemas, and I do not need to unmarshall this table(this is the next step). Has a JAXB a simple sax-parsing mechanism just for searching?
If you need to count before doing any unmarshalling, you won't need JAXB. JAXB is intended for binding XML to Java objects. For a task like this you could just use a parser (the StAX streaming API would be a good choice), but even easier would be to use an XSLT transformation. It won't require any additional dependencies, just using the XML transform API from Java.
A stylesheet that counts all <record>
elements within a table with a specific name:
<?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>
Check out the javax.xml.transform package. The Java runtime comes with an XSLT 1.0 transformer (based on Apache Xalan) by default. Your entry point for obtaining a transformer will be the TransformerFactory class . There's tutorials to be found online.
You can make the stylesheet a bit more flexible by supplying the table name as a parameter:
<?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>
The parameter value can then be supplied using method setParameter on a Transformer . The value in the stylesheet then acts as a default if it's not given by your code.
With a bit of experimentation you'd be able to output a file with the record counts for every table by name, like so:
T_NAME=3
T_OTHER=4
...
Might be useful if you have to do this for multiple tables. XSLT in Java is pretty fast and has decent memory usage, especially for a simple stylesheet like this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.