JAXB更改了元素"名称" of @XMLElements批注

时间:2017-10-18 10:08:02

标签: java xml jaxb

我的问题的根源是具有变量节点名称的给定XML。 XML已在使用中,无法更改。

我为XML创建了一个XSD来生成相应的Classes,然后通过DOMParser解析它。

我使用DOMParser是因为通过JAXB,由于变量标签名称而无法解析,但生成的类是有用的。

现在我只需要在类中使用变量节点的标识符。我认为最好只更改@XmlElement Annotations元素" name"并给它一个像#34;?"识别变量节点,但我不知道是否以及如何更改它。

我已经创建了一个剧集文件来更改某些类名,并认为可以通过它更改但我没有找到解决方案。

示例XML:

 <Settings>
    <Window>
        <Position Top="5" Left="5"/>
    </Window>
    <OpenData>
        <variable>
            <TableData>
                <variable-column00 POS="1" Visible="true" SortDesc="true"/>
                <variable-column01 POS="3" Visible="true" SortDesc="true"/>
                <variable-column02 POS="2" Visible="true" SortDesc="true"/>
            </TableData>
        </variable>
        <variable>
            <UserSettings>
                <variable-series1 Color="blue" Caption="Series blue" Visible="true" />
                <variable-series2 Color="yellow" Caption="Series yellow" Visible="true" />
                <variable-series3 Color="red" Caption="Series red" Visible="true" />
            </UserSettings>
            <ChartConfig>configuration-json....</ChartConfig>
        </variable>
        <variable/>
    </OpenData>
  </Settings>

变量节点将是: 名称为&#34;变量&#34;的节点,以&#34开头的节点;变量列&#34;和一些数字(表数据的子节点)和以&#34开头的节点;变量系列&#34;和一个数字(用户设置的子节点)

XSD将是:

    <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">

  <xs:complexType name="Window">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:sequence>
            <xs:element name="Position" type="Position" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Position">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:attribute name="Top" type="xs:int" />
        <xs:attribute name="Left" type="xs:int" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="OpenData">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:sequence>
            <!-- this would be the "variable" Node -->
            <xs:element name="View" type="View" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>


  <xs:complexType name="View">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:sequence>
        <!-- normaly the order would be random, but because i use the DOMParser i don't need to pass that to JAXB -->
        <xs:element name="TableData" type="TableData" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="UserSettings" type="UserSettings" minOccurs="0" maxOccurs="1" />
        <xs:element name="ChartConfig" type="xs:string" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="UserSettings">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:sequence>
        <!-- the next Variable Node name beginning with "variable-series" and then a number -->
        <xs:element name="SeriesDefinition" type="SeriesDefinition" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="SeriesDefinition">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:attribute name="Color" type="xs:string" />
        <xs:attribute name="Caption" type="xs:string" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>


  <xs:complexType name="TableData">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:sequence>
        <!-- the next Variable Node name beginning with "variable-column" and then a number -->
        <xs:element name="Column" type="Column" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Column">
    <xs:complexContent>
      <xs:extension base="SettingsElement">
        <xs:attribute name="POS" type="xs:int" />
        <xs:attribute name="Visible" type="xs:boolean" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="SettingsElement">
  </xs:element>


  <xs:element name="Settings" >
    <xs:complexType>
          <xs:sequence>
            <xs:element name="Window" type="Window" minOccurs="0" />
            <xs:element name="OpenData" type="OpenData" minOccurs="0" />
          </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

在我生成它之后,带有List of View的Class OpenData就是这样的:

import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OpenData", propOrder = {
    "view"
})
public class OpenData extends SettingsElement implements Serializable {

    private final static long serialVersionUID = 1L;
    @XmlElement(name = "View")
    protected java.util.List<View> view;

    public java.util.List<View> getview() {
        if (view == null) {
            view = new ArrayList<View>();
        }
        return this.view;
    }

}

我需要一个标识符来解析我的解析工作,因此更改注释

@XmlElement(name = "View")

@XmlElement(name = "?")

所以我知道我正在搜索的标签名称不是View,但可能是任何内容。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我的解决方案是改变发电机。

首先我像这样重新调整我的pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>


    <groupId>com.example</groupId>
    <artifactId>my-generator</artifactId>
    <version>1.0.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.jvnet.jaxb2_commons</groupId>
      <artifactId>jaxb2-basics-tools</artifactId>
      <version>1.11.1</version>
    </dependency>
  </dependencies>

  <build>

    <plugins>
      <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <executions>
          <execution>
            <id>example</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>generate</goal>
            </goals>
            <inherited>false</inherited>
            <configuration>
              <schemaDirectory>src/main/resources/META-INF/schemas/</schemaDirectory>
              <schemaIncludes>
                <include>configuration.xsd</include>
              </schemaIncludes>

              <generateDirectory>${project.build.directory}/generated-sources/</generateDirectory>
              <generatePackage>com.example.config</generatePackage>
              <extension>true</extension>
              <args>
                <arg>-Xannotate</arg>
              </args>

              <plugins>
                <plugin>
                  <groupId>org.jvnet.jaxb2_commons</groupId>
                  <artifactId>jaxb2-basics-annotate</artifactId>
                  <version>1.0.1</version>
                </plugin>
              </plugins>
            </configuration>
          </execution>
          </executions>
      </plugin>
    </plugins>
  </build>
</project>

我使用了org.jvnet.jaxb2.maven2.maven-jaxb2-plugin,因为它易于与jaxb2-basics-annotate插件一起使用。 我给了generationplugin一个带有Id,一个阶段和目标的执行,然后在执行的配置中,我向它展示了xsd文件的路径并命名了要使用的wich schema。然后我告诉它在哪里放置输出并给它一个参数,&#34; -Xannotate&#34;这是重要的部分,使用它和给定的插件可以通过* .xjb文件(绑定文件)更改注释

我将我的* .episode文件更改为* .xjb文件,因为生成器可以自动检测它们并添加行以更改&#34; XmlElement&#34;注释:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:annox="http://annox.dev.java.net" jxb:extensionBindingPrefixes="Xequals annox" xmlns:javaee="http://java.sun.com/xml/ns/javaee" version="2.1">


  <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xjc:serializable uid="1" />
  </jxb:globalBindings>

  <jxb:bindings schemaLocation="configuration.xsd">
    <jxb:bindings node="//xs:element[@name='Settings']">
      <jxb:bindings node="//xs:element[@name='OpenData']">
        <jxb:bindings node="//xs:element[@name='View']">
          <annox:annotate target="field">@javax.xml.bind.annotation.XmlElement(name="?")</annox:annotate>
          <jxb:bindings node="//xs:element[@name='TableData']">
            <jxb:bindings node="//xs:element[@name='Column']">
              <annox:annotate target="field">@javax.xml.bind.annotation.XmlElement(name="?")</annox:annotate>
            </jxb:bindings>
          </jxb:bindings>
          <jxb:bindings node="//xs:element[@name='UserSettings']">
            <jxb:bindings node="//xs:element[@name='SeriesDefinition']">
              <annox:annotate target="field">@javax.xml.bind.annotation.XmlElement(name="?")</annox:annotate>
            </jxb:bindings>
          </jxb:bindings>
        </jxb:bindings>
      </jxb:bindings>
    </jxb:bindings>
  </jxb:bindings>
</jxb:bindings>

现在在Generated Java Class中,例如UserSettings变量SeriesDefinition的XmlElement注释是:

@XmlElement(name = "?")

使用Reflection我可以得到这个Annotation并检查&#34; name&#34;属性是&#34;?&#34;并写一个名称值我可以给这个类。 当然,只有在每个类中最多只有一个带有Annotation XmlElement(name =&#34;?&#34;)的变量时,这才有效,我必须首先得到所有其他具有已定义名称的Tag,其余的已经是具有变量名称的那些。