如何在没有根类和模式的情况下通过JAXB使用xml?

时间:2017-03-30 11:51:51

标签: java xml jaxb sax

我有一个大型的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机制,只是用于搜索吗?

1 个答案:

答案 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速度非常快,内存使用率也不错,特别是对于像这样的简单样式表。