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



>我有一个大的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>

现在我需要用 name="T_NAME" 计算一个表中的记录。我没有任何架构,也不需要解组此表(这是下一步)。JAXB 是否只是为了搜索而使用简单的萨克斯解析机制?

如果你需要在执行任何解组之前计数,你将不需要 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 类。网上有教程。

您可以通过提供表名作为参数来使样式表更加灵活:

<?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 提供参数值。样式表中的值将充当默认值(如果代码未给出)。

通过一些实验,您将能够按名称输出一个包含每个表的记录计数的文件,如下所示:

T_NAME=3
T_OTHER=4
...

如果必须对多个表执行此操作,可能会很有用。Java 中的 XSLT 非常快,并且内存使用率不错,特别是对于像这样的简单样式表。

最新更新