【问题标题】:JAXB change the Element "name" of @XMLElements annotationJAXB 更改 @XMLElements 注释的元素“名称”
【发布时间】:2017-10-18 10:08:02
【问题描述】:

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

我为 XML 创建了一个 XSD 以生成相应的类,然后通过 DOMParser 对其进行解析。

我使用 DOMParser 是因为通过 JAXB 它是不可解析的,因为变量标签名但生成的类很有帮助。

现在我只需要类中变量节点的标识符。我认为最好只更改@XmlElement Annotations 元素“名称”并给它一个类似“?”的值。识别变量节点,但我不知道是否以及如何更改它。

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

示例 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>

变量节点将是: 名称为“variable”的节点,以“variable-column”和数字开头的节点(表数据的子节点)以及以“variable-series”和数字开头的节点(用户设置的子节点)

为此的 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>

在我生成它之后,带有视图列表的类 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,但可以是任何东西。

提前感谢您的帮助。

【问题讨论】:

标签: java xml jaxb


【解决方案1】:

我的解决方案是更换发电机。

首先我像这样重新调整我的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 模式。然后我告诉它在哪里放置输出并给它一个参数“-Xannotate”,这是重要的部分,使用它和给定的插件可以通过 *.xjb 文件(绑定文件)更改注释

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

<?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>

现在在生成的 Java 类中,例如UserSettings 变量 SeriesDefinition 的 XmlElement 注解为:

@XmlElement(name = "?")

通过反射我可以得到这个注释并检查“名称”属性是否为“?”并写在一个名称值中,我可以给班级。 当然,这仅在每个类中最多有一个带有注释 XmlElement(name = "?") 的变量时才有效,我必须首先获取具有已定义名称的所有其他标签,其余标签必须是带有变量的标签名字。

【讨论】:

    猜你喜欢
    • 2017-11-16
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2011-08-26
    • 1970-01-01
    相关资源
    最近更新 更多