JAXB XJC编译器忽略XML Schema文档中的mixed=true。

14

XJC似乎完全忽略了我的XML Schema元素上的mixed="true",从而不允许我提取文本内容。从下面的示例XML中,我需要能够提取“Title Text”。如果没有识别到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
{
}

为什么XJC / JAXB完全忽略了我的混合内容字段?我尝试过JAXB 2.1和JAXB 2.2,但生成的代码中只有微不足道的差异。

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


BIN类是什么样子的? - bdoughan
@Blaise - 我现在已经包含了一个小但完整的模式,展示了这个问题。 - Kaleb Pederson
你曾经找到解决这个问题的方法吗?我也遇到了同样的问题。我不得不编辑生成的类(BIN)。 - AHungerArtist
最终我提交了一个错误报告,我会在回答中提供链接。 - Kaleb Pederson
3个回答

8

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 参数,以您通常的方式完成操作。

我记得当时看到过那篇帖子,如果我没记错的话,我的问题略有不同,但是有关联。但是...我现在已经不能太确定地记得了。 - Kaleb Pederson
1
它确实创建了一个内容字段,不幸的是它是一个丑陋的List<Serializable>,但这比没有要好,特别是因为我也在使用HL7模式。事实上,这就是我之前遇到问题的那个类。 - AHungerArtist

5

经过更多的研究,我得出的结论只能是这是一个错误,并且我已经提出了错误报告。它被确认为JAXB问题#792


4
多年过去了,但这个方案仍然困扰着人们!我过去几天一直在处理这个相同的XSD(HL7),特别是处理混合内容元素类型方面苦苦挣扎。
我的最初需求与原帖相反,因为我需要在混合元素中写入简单文本。但我必须能够读取这样的内容,所以我应用了另一个回复中提供的相同解决方案,即创建自定义绑定文件并在Eclipse的“JAXB Classes from Schema”向导中使用它。
这种情况下,当发现混合元素类型时,类会生成具有List<Serializable>内容。提取实际需要的单个信息有点棘手,但至少您可以编程访问遵循该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等本身就是混合的(对于我们的目的,我们不需要知道其他内容)。

因此,当您访问名称的内容时,它的List<Serializable>将由以下内容组成:

  1. 一个String,即<v3:name><v3:given>之间的空白
  2. 一个EnGiven元素
  3. 一个String,即</v3:given><v3:family>之间的空白
  4. 一个EnFamily元素
  5. 一个String,即</v3:family></v3:name>之间的空白

EnGivenEnFamily的内容分别由单个String"样本给定名称"和"样本家庭名称"组成。再次说明,这有点棘手,您可能需要处理特定情况的逻辑,但您可以以这种方式处理。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接