【问题标题】:How to get jaxb to Ignore certain data during unmarshalling如何让 jaxb 在解组期间忽略某些数据
【发布时间】:2011-02-25 00:49:02
【问题描述】:

我有一个 xml 结构“过滤器”,它被解组到一个名为“过滤器”的 java 类中。

XML 状态大致如下:

<filter>
  <propertyType>
    <propertyName>prop1</propertyName>
    <propertyValue>val1</propertyValue>
  </propertyType>
  <propertyType>
    <propertyName>prop2</propertyName>
    <propertyValue>val2</propertyValue>
  </propertyType>
</filter>

通常,它工作得很好。

但是,在某些情况下,这些属性值之一本身包含 xml 结构(请参阅下面的第二个 propertyValue):

<filter>
  <propertyType>
    <propertyName>prop1</propertyName>
    <propertyValue>val1</propertyValue>
  </propertyType>
  <propertyType>
    <propertyName>prop2</propertyName>
    <propertyValue><nodeA><nodeB>valB</nodeB></nodeA></propertyValue>
  </propertyType>
</filter>

这里的问题是,解组这个结构后,propertyValue为null。

我希望能够让解组忽略这个看起来像 xml 的代码并将其视为一个简单的字符串值。

有谁知道我如何做到这一点?感谢您的回复!

【问题讨论】:

    标签: java xml service jaxb


    【解决方案1】:

    使用“@XmlAnyElement”的注解怎么样? 您可以获取 org.w3c.dom.Element 的实例。 操作这个实例应该可以得到文本数据。

    class PropertyType {
        private String propertyName;
        // private String propertyValue; // comment out
        @XmlAnyElement(lax=true)
        private List<org.w3c.dom.Element> propertyValue; // Adding this
    }
    

    获取文本数据的示例。

    // It is assumed that the child node is one. 
    org.w3c.dom.Node nd = propertyValue.get(0).getFirstChild();
    while(true) {
        if (nd.hasChildNodes()) {
            nd = nd.getFirstChild();
        } else {
            System.out.println(nd.getNodeValue()); // this is text data
            break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      对于这个用例,我将创建一个将转换 XML 文档的 XSLT。然后使用 javax.xml.transform.* API,将 XML 转换为 JAXBResult 以解组对象:

      import java.io.File;
      import javax.xml.bind.JAXBContext;
      import javax.xml.bind.util.JAXBResult;
      import javax.xml.transform.Transformer;
      import javax.xml.transform.TransformerFactory;
      import javax.xml.transform.stream.StreamSource;
      
      public class Demo {
      
          public static void main(String[] args) throws Exception {
              TransformerFactory tf = TransformerFactory.newInstance();
      
              File xsltFile = new File("transform.xsl");
              StreamSource xsltSource = new StreamSource(xsltFile);
              Transformer transformer = tf.newTransformer(xsltSource);
      
              File xml = new File("input.xml");
              StreamSource xmlSource = new StreamSource(xml);
      
              JAXBContext jc = JAXBContext.newInstance(Filter.class);
              JAXBResult jaxbResult = new JAXBResult(jc);
      
              transformer.transform(xmlSource, jaxbResult);
      
              Filter filter = (Filter) jaxbResult.getResult();
          }
      
      }
      

      transform.xsl

      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:template match="node() | @*">
              <xsl:copy>
                  <xsl:apply-templates select="node() | @*" />
              </xsl:copy>
          </xsl:template>
          <xsl:template match="propertyValue"> <xsl:value-of select="descendents"/>
             <xsl:element name="propertyValue">
                 <xsl:value-of select="node()"/>
             </xsl:element>
          </xsl:template>
      </xsl:stylesheet>
      

      【讨论】:

      • @Alejandro:样式表为这个例子产生了正确的结果,尽管我同意可能有更好的方法来编写它。我回答的重点是可以使用 JAXB 和 XSLT 的组合来实现预期的结果。
      【解决方案3】:

      AFAIK JAXB 在 xml 模式上工作,用于将 XML 解组为 Java 对象。因此,如果架构将元素定义为简单元素,则它只能包含文本。如果您需要将 XML 存储为简单文本。您可能需要使用 CDATA 构造对其进行转义。尝试如下所示包含相同的内容,解组后您将获得 XML 原样。

      <filter>
        <propertyType>
          <propertyName>prop1</propertyName>
          <propertyValue>val1</propertyValue>
        </propertyType>
        <propertyType>
          <propertyName>prop2</propertyName>
          <propertyValue><![CDATA[<nodeA><nodeB>valB</nodeB></nodeA>]]></propertyValue>
        </propertyType>
      </filter>
      

      【讨论】:

      • 糟糕,糟糕的建议。不要将可解析的数据视为未解析的数据。
      猜你喜欢
      • 2010-09-21
      • 2021-06-08
      • 2018-03-10
      • 2015-06-19
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多