JAXB XJC 编译器忽略 XML 架构文档上的 mix=true

发布于 2024-09-29 20:50:54 字数 3626 浏览 6 评论 0原文

XJC 似乎完全忽略了我的 XML 架构元素上的 mixed="true" ,因此不允许我提取文本内容。我需要能够从下面的示例 XML 中提取“标题文本”。如果 mixed="true" 未被识别,则不会创建访问器,也不会从 XML 中解组:

<?xml version="1.0" encoding="UTF-8"?>
<title xmlns="urn:hl7-org:v3" integrityCheck="true">Title Text</title>

这是一个完整但最小化的架构,它演示了该问题:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema targetNamespace="urn:hl7-org:v3"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns="urn:hl7-org:v3"
  xmlns:mif="urn:hl7-org:v3/mif"
  elementFormDefault="qualified">

  <xs:complexType name="ST" mixed="true">
  <xs:complexContent>
         <xs:restriction base="ED">
            <xs:sequence>
               <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="0"/>
               <xs:element name="thumbnail" type="xs:string" minOccurs="0" maxOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="compression" type="xs:string" use="prohibited"/>
         </xs:restriction>
      </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ED" mixed="true">
    <xs:complexContent>
      <xs:extension base="BIN">
        <xs:sequence>
          <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="1" />
          <xs:element name="thumbnail" minOccurs="0" maxOccurs="1" type="xs:string" />
            </xs:sequence>
        <xs:attribute name="compression" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheck" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheckAlgorithm" type="xs:string" use="optional" default="SHA-1" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="BIN" abstract="true" mixed="true">
    <xs:complexContent>
      <xs:extension base="ANY">
        <xs:attribute name="representation" use="optional" type="xs:string" default="TXT" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ANY" abstract="true">
    <xs:attribute name="nullFlavor" type="xs:string" use="optional" />
  </xs:complexType>

  <xs:element name="title" type="ST" />
</xs:schema>

请注意,在上面我有 mixed="true" 。尽管如此,生成的架构片段不包含对其的引用,生成的类也不使用 XmlMixed 注释,也不使用值或内容访问器:

/**
 * <p>Java class for ST complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.                                                                                                                                              
 * 
 * <pre>
 * <complexType name="ST">
 *   <complexContent>
 *     <restriction base="{urn:hl7-org:v3}ED">
 *       <sequence>
 *         <element name="reference" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *         <element name="thumbnail" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * </pre>
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ST")
public class ST
    extends ED
{
}

Why is XJC / JAXB完全忽略我的混合内容领域?我已经尝试过 JAXB 2.1 和 JAXB 2.2,但生成的代码中仅存在细微的差异。

注意:我无法更改架构,因为实际架构是符合标准的医疗保健 (HL7) 架构。

XJC seems to be completely ignoring mixed="true" on my XML Schema elements thereby not allowing me to extract text content. From the sample XML below, I need to be able to extract "Title Text." Without mixed="true" being recognized, no accessor is created nor is it unmarshalled from XML:

<?xml version="1.0" encoding="UTF-8"?>
<title xmlns="urn:hl7-org:v3" integrityCheck="true">Title Text</title>

Here's a complete but minimized schema that demonstrates the problem:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema targetNamespace="urn:hl7-org:v3"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns="urn:hl7-org:v3"
  xmlns:mif="urn:hl7-org:v3/mif"
  elementFormDefault="qualified">

  <xs:complexType name="ST" mixed="true">
  <xs:complexContent>
         <xs:restriction base="ED">
            <xs:sequence>
               <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="0"/>
               <xs:element name="thumbnail" type="xs:string" minOccurs="0" maxOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="compression" type="xs:string" use="prohibited"/>
         </xs:restriction>
      </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ED" mixed="true">
    <xs:complexContent>
      <xs:extension base="BIN">
        <xs:sequence>
          <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="1" />
          <xs:element name="thumbnail" minOccurs="0" maxOccurs="1" type="xs:string" />
            </xs:sequence>
        <xs:attribute name="compression" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheck" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheckAlgorithm" type="xs:string" use="optional" default="SHA-1" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="BIN" abstract="true" mixed="true">
    <xs:complexContent>
      <xs:extension base="ANY">
        <xs:attribute name="representation" use="optional" type="xs:string" default="TXT" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ANY" abstract="true">
    <xs:attribute name="nullFlavor" type="xs:string" use="optional" />
  </xs:complexType>

  <xs:element name="title" type="ST" />
</xs:schema>

Note that in the above I have mixed="true". Despite that, the generated schema fragment doesn't contain a reference to it, nor does the generated class use the XmlMixed annotation, nor a value or contents accessor:

/**
 * <p>Java class for ST complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.                                                                                                                                              
 * 
 * <pre>
 * <complexType name="ST">
 *   <complexContent>
 *     <restriction base="{urn:hl7-org:v3}ED">
 *       <sequence>
 *         <element name="reference" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *         <element name="thumbnail" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * </pre>
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ST")
public class ST
    extends ED
{
}

Why is XJC / JAXB completely disregarding my mixed content fields? I have tried both JAXB 2.1 and JAXB 2.2 but only trivial differences are present in the generated code.

Note: I can't change the schema as the actual schema is a standards-compliant healthcare (HL7) schema.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

子栖 2024-10-06 20:50:54

http://blogs.oracle.com/mgrebac/entry/handling_extended_mixed_content_in

这有效!只需像这样创建一个绑定文件:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
 xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings generateMixedExtensions="true"/>
</jaxb:bindings>

然后按照通常的方式在命令行上使用 -b 参数。

http://blogs.oracle.com/mgrebac/entry/handling_extended_mixed_content_in

This worked! Just create a binding file like so:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
 xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings generateMixedExtensions="true"/>
</jaxb:bindings>

Then use the -b parameter on the command line with the way you usually do it.

时光倒影 2024-10-06 20:50:54

经过更多研究后,我无能为力,只能得出结论,这是我提交的一个错误。它被确认为 JAXB 问题 #792

After more research I could do nothing but conclude it was a bug which I filed. It was acknowledged as JAXB issue #792.

二货你真萌 2024-10-06 20:50:54

这么多年过去了,这个计划却一直困扰着人们!在过去的几天里,我一直在努力解决同样的 XSD (HL7),特别是在处理混合内容元素类型方面。

我最初的要求与原始海报相反,因为我需要在混合元素内编写简单的文本。但我也必须能够阅读此类内容,因此我应用了另一个回复中建议的相同解决方案,即创建一个自定义绑定文件并在 Eclipse 的“来自架构的 JAXB 类”向导中使用它。
在这种情况下,您可以在向导的对话框之一中专门选择要使用的绑定文件。

因此,只要找到混合元素类型,就会生成带有 List 内容的类。提取您实际需要的单条信息有点棘手,但至少您确定可以通过编程方式访问附着该 XSD 的 XML 文件中存在的任何内容。

您甚至可以导航到更复杂的混合内容,例如:

<v3:name>
    <v3:given>Sample Given Name</v3:given>
    <v3:family>Sample Family Name</v3:family>
</v3:name>

name 的定义如下(我从原始 XSD 中删除了对此示例无用的内容):

<xs:complexType name="EN" mixed="true">
    <xs:complexContent>
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="delimiter" type="en.delimiter"/>
                <xs:element name="family" type="en.family"/>
                <xs:element name="given" type="en.given"/>
                <xs:element name="prefix" type="en.prefix"/>
                <xs:element name="suffix" type="en.suffix"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexContent>
</xs:complexType>

类型 en.familyen.given 等本身是混合的(出于我们的目的,我们不需要知道其他任何东西)。

因此,当您访问 name 的内容时,其 List 将由以下部分组成:

  1. 一个 String,即 之间的空格。 code> 和
  2. 一个 EnGiven 元素是
  3. 一个 String,是 之间的空格。
  4. 是一个 EnFamily 元素
  5. ,一个 String,即

EnGivenEnFamily 的内容将分别由单个 String,分别为“示例名字”和“示例姓氏”。同样,这有点棘手,您可能必须添加一些逻辑来处理特定情况,但您可以通过这种方式进行管理。

顺便说一下,填充一个元素很简单:只需将一个字符串添加到所需的 List 内容中即可。

Years pass by, but this scheme keeps troubling people! I've been struggling with this same XSD (HL7) for the past few days, especially for handling the mixed content element types.

My initial requirment was the opposite of the original poster, as I needed to write simple text inside a mixed element. But I must be able to also read such content, so I applied the same solution suggested in another reply, that is creating a custom binding file and using it in Eclipse's "JAXB Classes from Schema" wizard.
In that case you can specifically choose which binding file(s) to use in one of the wizard's dialogs.

As a result, classes are generated with a List<Serializable> content whenever a mixed element type is found. It gets a bit tricky to extract the single piece of information you actually need, but at least you're sure you can programatically access anything that's present in an XML file adhering that XSD.

You can even navigate into more complex mixed contents such as:

<v3:name>
    <v3:given>Sample Given Name</v3:given>
    <v3:family>Sample Family Name</v3:family>
</v3:name>

Where name is defined as such (I removed content not useful for this example from the original XSD):

<xs:complexType name="EN" mixed="true">
    <xs:complexContent>
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="delimiter" type="en.delimiter"/>
                <xs:element name="family" type="en.family"/>
                <xs:element name="given" type="en.given"/>
                <xs:element name="prefix" type="en.prefix"/>
                <xs:element name="suffix" type="en.suffix"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexContent>
</xs:complexType>

Types en.family, en.given and such are mixed themselves (and for our purpose we don't need to know anything else).

So, when you access name's content, its List<Serializable> will be composed of:

  1. a String, being the blanks between <v3:name> and <v3:given>
  2. an EnGiven element
  3. a String, being the blanks between </v3:given> and <v3:family>
  4. an EnFamily element
  5. a String, being the blanks between </v3:family> and </v3:name>

EnGiven and EnFamily's content will be each made of a single String, respectively "Sample Given Name" and "Sample Family Name". Again, it is a bit tricky, and you have probably have to put some logic to handle the specific cases, but you can manage it this way.

By the way, populating an element is trivial: just add a String to the desired List<Serializable> content.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文