如何删除输入xml中的空标记

时间:2010-05-21 17:39:28

标签: java xml jaxb

我的java模块从大型机获取巨大的输入xml。不幸的是,大型机无法跳过可选元素,结果我在输入中得到了很多空标记:

所以,

<SSN>111111111</SSN>
<Employment>
<Current>
<Address>
<line1/>
<line2/>
<line3/>
<city/>
<state/>
<country/>
</Address>
<Phone>
<phonenumber/>
<countryCode/>
</Phone>
</Current>
<Previous>
<Address>
<line1/>
<line2/>
<line3/>
<city/>
<state/>
<country/>    
</Address>
<Phone>
<phonenumber/>
<countryCode/>
</Phone>
</Previous>
</Employment>
<MaritalStatus>Single</MaritalStatus>

应该是:

<SSN>111111111</SSN>
<MaritalStatus>SINGLE</MaritalStatus>

我使用jaxb解组大型机发送的输入xml字符串。是否有一种干净/简单的方法来删除所有空组标签,或者我必须在每个元素的代码中执行此操作。我的输入xml中有超过350个元素,所以如果jaxb本身有办法自动执行此操作,我会很喜欢吗?

谢谢, SGB

5 个答案:

答案 0 :(得分:4)

您可以使用XSLT进行预处理。我知道它现在被认为有点“迪斯科”,但它应用起来既快速又容易。

从这个tek-tips讨论中,您可以使用XSLT进行转换以删除空元素。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:if test=". != '' or ./@* != ''">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:4)

我认为您必须编辑大型机代码以获得最佳解决方案。当您的大型机生成XML时,如果标记为空,则必须告诉它不要输出标记。

你不能在客户端做多少我不这么认为。如果您获得的XML填充了空标记,那么您别无选择,只能将它们全部解析 - 毕竟,如果标记为空而不以某种方式解析它,您如何判断它是否为空!

但也许你可以在JAX-B到达之前对XML文本进行正则表达式字符串替换:

String xml = //get the XML
xml = xml.replaceAll("<.*?/>", "");

这将删除“&lt; city /&gt;”之类的空标签但不是“&lt;地址&gt;&lt; /地址&gt;”。

答案 2 :(得分:1)

我在JAXB中知道的唯一一项技术就是编写一个自定义XmlAdapter,将空字符串折叠为空。

缺点是你必须将它作为注释添加到代码中的每个元素,如果你有350个,那将是乏味的。

答案 3 :(得分:1)

好的,反过来介入这里。 使用jaxb的简单工作解决方案(至少对于jdk 1.6.x):

将不需要的属性或元素设置为null! 例如... setEmployment(NULL); 然后整个就业结构都消失了。

干杯 马西

答案 4 :(得分:0)

 public static void main(String[] args) {

    final String regex1 = "<([a-zA-Z][a-zA-Z0-9]*)[^>]*/>";
    final String regex2 = "<([a-zA-Z][a-zA-Z0-9]*)[^>]*>\\s*</\\1>";

    String xmlString = "<SSN>111111111</SSN><Employment><Current><Address><line1/><line2/><line3/><city/><state/><country/></Address><Phone><phonenumber/><countryCode/></Phone></Current><Previous><Address><line1/><line2/><line3/><city/><state/><country/>    </Address><Phone><phonenumber/><countryCode/></Phone></Previous></Employment><MaritalStatus>Single</MaritalStatus>";
    System.out.println(xmlString);

    final Pattern pattern1 = Pattern.compile(regex1);
    final Pattern pattern2 = Pattern.compile(regex2);

    Matcher matcher1;
    Matcher matcher2;
    do {
        matcher1 = pattern1.matcher(xmlString);
        matcher2 = pattern2.matcher(xmlString);
        xmlString = xmlString.replaceAll(regex1, "").replaceAll(regex2, "");
    } while (matcher1.find() || matcher2.find());

    System.out.println(xmlString);
}

控制台:

<SSN>111111111</SSN>
<Employment>
    <Current>
        <Address>
            <line1/>
            <line2/>
            <line3/>
            <city/>
            <state/>
            <country/>
        </Address>
        <Phone>
            <phonenumber/>
            <countryCode/>
        </Phone>
    </Current>
    <Previous>
        <Address>
            <line1/>
            <line2/>
            <line3/>
            <city/>
            <state/>
            <country/>
        </Address>
        <Phone>
            <phonenumber/>
            <countryCode/>
        </Phone>
    </Previous>
</Employment>
<MaritalStatus>Single</MaritalStatus>

<SSN>111111111</SSN>
<MaritalStatus>Single</MaritalStatus>

Online demo here