jjzjj

xml - 处理 JAXB 枚举键名

coder 2024-07-02 原文

最近几天我一直在为我的 jaxb 问题寻找解决方案,但没有成功......所以我希望这里有人可以帮助我。

基础是来自外部合作伙伴的 xsd 架构,它是原样的,即我无法更改它。这些类是用 xjc 生成的,没有问题,但枚举不是“java 兼容的”。 有些值是数字或字母数字,因此必须在绑定(bind)中设置属性 typesafeEnumMemberName="generateName"。

然后 Jaxb 生成枚举键,如 VALUE_1、VALUE_2 等。我现在的问题是,一些枚举有 < 250="" 个条目,只有条目的="" javadoc="" 说明了有关值的信息。="" 这不是很舒服,并且会导致错误,因为以下="" mandattype="" 枚举的值="" value_1="" 的值为“e”而不是“1”......="">

<xsd:simpleType name="MandatType">
    <xsd:annotation>
        <xsd:documentation/>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
        <xsd:maxLength value="1"/>
        <xsd:minLength value="1"/>
        <xsd:enumeration value="E">
            <xsd:annotation>
                <xsd:documentation>Erinnerung</xsd:documentation>
            </xsd:annotation>
        </xsd:enumeration>
        <xsd:enumeration value="1">
            <xsd:annotation>
                <xsd:documentation>Klage</xsd:documentation>
            </xsd:annotation>
        </xsd:enumeration>
        <xsd:enumeration value="2">
            <xsd:annotation>
                <xsd:documentation>Beschaffung</xsd:documentation>
            </xsd:annotation>
        </xsd:enumeration>
        <xsd:enumeration value="Z">
            <xsd:annotation>
                <xsd:documentation>Storno</xsd:documentation>
             </xsd:annotation>
        </xsd:enumeration>
    </xsd:restriction>
</xsd:simpleType>

类(class):

@XmlType(name = "MandatType")
@XmlEnum
public enum MandatType {
    /**
     * Erinnerung 
     * 
     */
    @XmlEnumValue("E")
    VALUE_1("E"),

    /**
     * Klage
     * 
     */
    @XmlEnumValue("1")
    VALUE_2("1"),

    /**
     * Beschaffung
     * 
     */
    @XmlEnumValue("2")
    VALUE_3("2"),

    /**
     * Storno
     * 
     */
    @XmlEnumValue("Z")
    VALUE_Z("Z"),

    //...
}

我找到的唯一解决方案是为绑定(bind)中的每个枚举值定义枚举键。但问题是,这大约有 14.000 个值! 那么有没有人有其他想法来解决这个问题?是否可以定义一种方法来在 xjc 生成类时覆盖/更改枚举值?或者使用 xsd:documentation 值作为枚举的键?

非常感谢 斯蒂芬

最佳答案

可以编写您自己的 JAXB 插件,然后可以使用该插件合并任意数据以修改生成的代码。这link有一些提示,您可以探索这些提示以获取更多信息。

或者,您可能会考虑更简单的方法(在我看来),那就是将您的 XSD 重构为可以使用开箱即用功能的东西。

如果你想要的只是沿着这些路线,转换它:

    <xsd:enumeration value="E">
        <xsd:annotation>
            <xsd:documentation>Erinnerung</xsd:documentation>
        </xsd:annotation>
    </xsd:enumeration>

进入这个:

    <xsd:enumeration value="E">
        <xsd:annotation>
            <xsd:documentation>Erinnerung</xsd:documentation>
            <xsd:appinfo>
                <jaxb:typesafeEnumMember name="Erinnerung"/>
            </xsd:appinfo>              
        </xsd:annotation>
    </xsd:enumeration>

那么我认为基本的 XSLT 技能应该可以帮助您解决这个问题,这比编写 JAXB 插件或使用 XSOM 等要好。在这些情况下,14000 左右应该没什么区别。即使您的模式分布在数百个文件中,仍然可以更轻松地调整一次执行一个模式的愚蠢 XSLT,然后简单地为每个文件生成命令行...

这是一个简单的 XSLT:

<xsl:stylesheet version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

    <xsl:template match="xsd:enumeration">
        <xsd:enumeration>
            <xsl:attribute name="value">
                <xsl:value-of select="@value"/>
            </xsl:attribute>
            <xsd:annotation>
                <xsl:copy-of select="xsd:annotation/xsd:documentation"/>
                <xsd:appinfo>
                    <jaxb:typesafeEnumMember>
                        <xsl:attribute name="name">
                             <xsl:value-of select="xsd:annotation/xsd:documentation"/>
                        </xsl:attribute>
                    </jaxb:typesafeEnumMember>
                </xsd:appinfo>                          
            </xsd:annotation>
        </xsd:enumeration>
    </xsl:template>
</xsl:stylesheet>

可以用模板调用替换简单的文档“转储”,模板调用可以处理文本,或提供替代方案,或针对特定条件发出消息等。

生成的输出可能如下所示:

<?xml version="1.0" encoding="utf-16"?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xtm="http://paschidev.com/schemas/metadata/xtm">
    <xsd:simpleType name="MandatType">
        <xsd:annotation>
            <xsd:documentation/>
        </xsd:annotation>
        <xsd:restriction base="xsd:string">
            <xsd:maxLength value="1"/>
            <xsd:minLength value="1"/>
            <xsd:enumeration value="E">
                <xsd:annotation>
                    <xsd:documentation>Erinnerung</xsd:documentation>
                    <xsd:appinfo>
                        <jaxb:typesafeEnumMember name="Erinnerung"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:enumeration>
            <xsd:enumeration value="1">
                <xsd:annotation>
                    <xsd:documentation>Klage</xsd:documentation>
                    <xsd:appinfo>
                        <jaxb:typesafeEnumMember name="Klage"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:enumeration>
            <xsd:enumeration value="2">
                <xsd:annotation>
                    <xsd:documentation>Beschaffung</xsd:documentation>
                    <xsd:appinfo>
                        <jaxb:typesafeEnumMember name="Beschaffung"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:enumeration>
            <xsd:enumeration value="Z">
                <xsd:annotation>
                    <xsd:documentation>Storno</xsd:documentation>
                    <xsd:appinfo>
                        <jaxb:typesafeEnumMember name="Storno"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:enumeration>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

关于xml - 处理 JAXB 枚举键名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32786230/

有关xml - 处理 JAXB 枚举键名的更多相关文章

  1. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  2. 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代码修改为

  3. Ruby-vips 图像处理库。有什么好的使用示例吗? - 2

    我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby​​代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby​​-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby​​-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby​​-vips的github页面上的链接,我们将不胜感激!如果有ruby​​-

  4. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  5. ruby - 如何使用 Ruby HTTP::Net 处理 404 错误? - 2

    我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。

  6. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  7. ruby-on-rails - Ruby on Rails,使用同名枚举的问题 - 2

    以下是我认为的一些下拉列表:'form-control')%>和'form-control')%>这是我的application_helper.rbdefget_advance_bookingret=[{:require_booking=>'No'},{:require_booking=>'Yes'}]enddefget_instant_bookingret=[{:instant_booking=>'No'},{:instant_booking=>'Yes'}]end但现在的问题是,在我的模型product.rb中,我无法设置具有相同名称的枚举:classProduct我收到的错误是您

  8. ruby-on-rails - 如何使用驼峰键名称从 Rails 返回 JSON - 2

    我正在构建一个带有Rails后端的JS应用程序,为了不混淆snake和camelcases,我想通过从服务器返回camelcase键名来规范化这一切。因此,当从API返回时,user.last_name将返回user.lastName。我如何实现这一点?谢谢!编辑:添加Controller代码classApi::V1::UsersController 最佳答案 我的方法是使用ActiveModelSerializer和json_api适配器:在你的Gemfile中,添加:gem'active_model_serializers'创建

  9. ruby-on-rails - 使用 Ruby 正确处理 Stripe 错误和异常以实现一次性收费 - 2

    我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)

  10. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

随机推荐