简体   繁体   中英

How to work with xml via JAXB without root classes and schemas?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM