从XML文档,XSLT和JAXB中删除元素

时间:2011-03-03 13:44:54

标签: java xml xslt xsd jaxb

这个问题是我之前提出的问题的后续问题: Creating a valid XSD that is open using <all> and <any> elements

鉴于我有一个包含以下格式的XML文档的Java String:

<TRADE>
  <TIME>12:12</TIME>
  <MJELLO>12345</MJELLO>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
  <HELLO>hello should be ignored</HELLO>
</TRADE>

如何使用XSLT或类似方法(在Java中使用JAXB)删除一组元素中未包含的所有元素。 在上面的示例中,我只对(TIME,OPTIONAL,DATE)感兴趣,所以我想将其转换为:

<TRADE>
  <TIME>12:12</TIME>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
</TRADE>

元素的顺序不固定。

3 个答案:

答案 0 :(得分:6)

此转化:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNames" select="'|TIME|OPTIONAL|DATE|'"/>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="*/*">
  <xsl:if test="contains($pNames, concat('|', name(), '|'))">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<TRADE>
    <TIME>12:12</TIME>
    <MJELLO>12345</MJELLO>
    <OPTIONAL>12:12</OPTIONAL>
    <DATE>25-10-2011</DATE>
    <HELLO>hello should be ignored</HELLO>
</TRADE>

会产生想要的正确结果:

<TRADE>
   <TIME>12:12</TIME>
   <OPTIONAL>12:12</OPTIONAL>
   <DATE>25-10-2011</DATE>
</TRADE>

<强>解释

  1. 身份规则(模板)按原样复制每个节点

  2. 标识规则被匹配任何不是文档顶部元素的元素的模板覆盖。在模板内部,检查匹配元素的名称是否是在管道分隔的有用名称字符串中的外部参数$pNames中指定的名称之一。

  3. 请参阅XSLT处理器的文档,了解如何将参数传递给转换 - 这与实现有关,因处理器而异。

答案 1 :(得分:1)

我还没有尝试过,但也许javax.xml.tranform包可以提供帮助:

http://download.oracle.com/javase/6/docs/api/javax/xml/transform/package-summary.html

答案 2 :(得分:1)

JAXB&amp; XSLT

JAXB非常干净地与XSLT集成,例如:

您的其他问题

根据您之前的问题(请参阅下面的链接),转换实际上是不必要的,因为JAXB将忽略未映射到域对象中的字段/属性的属性和元素。