草庐IT

xml - 从模式生成代码时删除中间类

coder 2024-06-24 原文

假设我们在 XSD 中定义了一个集合类型

<xs:complexType name="Foos">
  <xs:sequence>
    <xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
      <xs:complexType>
        <xs:all>
          <xs:element name="bar" type="xs:string"/>
          <xs:element name="baz" type="xs:string"/>
        </xs:all>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

当使用 XJC 从它生成 Java 代码时,类型大致转换为

public class Foos {
  public List<Foos.Foo> getFoos();

  public static class Foo {
    public String getBar();
    public String getBaz();
  }
}

由于集合类型是某些其他类型的一部分,例如文档的根,因此生成代码的客户端代码看起来有点像这样

for(Foo foo : document.getFoos().getFoos())
{
  //do something
}

有没有什么办法可以在不手动编写包装器的情况下使客户端代码不那么丑陋?

应该是这样的

for(Foo foo : document.getFoos())
{
  //do something
}

谢谢

最佳答案

更新

人们已经编写了 XJC 插件来生成 @XmlElementWrapper 注释,而不是拥有额外的包装器类。


原始答案

或者,您可以自己使用 @XmlElementWrapper 创建类,并通过执行以下操作让生成的类引用它:

文档

您可以手工制作您自己的 Document 类以获得所需的行为。您可以通过利用 @XmlElementWrapper 注释获取分组元素来获取您正在寻找的行为。

package forum18247182;

import java.util.*;
import javax.xml.bind.annotation.*;

public class Document {

    private List<Foos.Foo> foos = new ArrayList<Foos.Foo>();

    @XmlElementWrapper
    @XmlElement(name="foo")
    public List<Foos.Foo> getFoos() {
        return foos;
    }

}

XML 架构 (schema.xsd)

这是我将使用的基于您的片段的扩展 XML 模式。

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

    <xs:element name="document" type="Document"/>

    <xs:complexType name="Document">
        <xs:sequence>
            <xs:element name="foos" type="Foos"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Foos">
        <xs:sequence>
            <xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:all>
                        <xs:element name="bar" type="xs:string" />
                        <xs:element name="baz" type="xs:string" />
                    </xs:all>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

从 XML 架构 (binding.xml) 生成 Java 模型时利用现有类

我们将使用外部绑定(bind)文件来指示在类生成期间我们希望将现有类用于名为 Document 的复杂类型。

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">

    <jxb:bindings schemaLocation="schema.xsd">
        <jxb:bindings node="//xs:complexType[@name='Document']">
            <jxb:class ref="forum18247182.Document"/>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

新江西来电

我们将使用 -b 选项来指定我们的绑定(bind)文件。我们还将使用 -p 选项强制生成的类的包名与我们的 Document 类的包名相匹配。我们还可以让我们的 Document 类的包名与从 XML 模式生成类的包名相匹配。

xjc -b binding.xml -p forum18247182 schema.xsd

演示代码

package forum18247182;

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import forum18247182.Foos.Foo;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance("forum18247182");

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource xml = new StreamSource("src/forum18247182/input.xml");
        Document document = unmarshaller.unmarshal(xml, Document.class).getValue();

        for(Foo foo : document.getFoos())
        {
          System.out.println(foo);
        }
    }

}

输出

下面是运行演示代码的输出:

forum18247182.Foos$Foo@51f3336e
forum18247182.Foos$Foo@35b5a4ca

关于xml - 从模式生成代码时删除中间类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18247182/

有关xml - 从模式生成代码时删除中间类的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  6. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  7. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  8. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  9. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  10. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

随机推荐