具有多个字段的XML模式键

具有多个字段的XML模式键,xml,schema,xsd,Xml,Schema,Xsd,我有一个包含问题结构的XML文件格式: <question id="q101"> <text>Do you like the color red?</text> <answer>yes</answer> <answer>no</answer> </question> <question id="q102"> <text>What is your favorite

我有一个包含问题结构的XML文件格式:

<question id="q101">
  <text>Do you like the color red?</text>
  <answer>yes</answer>
  <answer>no</answer>
</question>
<question id="q102">
  <text>What is your favorite color?</text>
  <answer>red</answer>
  <answer>blue</answer>
  <answer>white</answer>
  <answer>yellow</answer>
</question>

你喜欢红色吗?
对
不
你最喜欢什么颜色?
红色
蓝色
白色
黄色的
我还有来自多个用户的相同文件响应

<user id="bob">
  <response questionIdRef="q101">yes</response>
  <response questionIdRef="q102">white</response>
</user>
<user id="jane">
  <response questionIdRef="q101">no</response>
  <response questionIdRef="q102">blue</response>
</user>

对
白色
不
蓝色
我已经在xml中为questionId定义了一个key和一个keyref元素:

<xsd:key name="questionId">
  <xsd:selector xpath=".//question" />
  <xsd:field xpath="@id" />
</xsd:key>
<xsd:keyref name="responseQuestionIdKeyRef" refer="questionId">
  <xsd:selector xpath=".//response" />
  <xsd:field xpath="@questionIdRef" />
</xsd:keyref>

我现在想做的是让模式验证用户对某个问题的响应值实际上是引用问题中提供的答案。我尝试使用以下键和keyref执行此操作,但它只会识别第一个答案,其他所有答案都不被识别为有效:

<xsd:key name="answerValue">
  <xsd:selector xpath=".//question" />
  <xsd:field xpath="@id" />
  <xsd:field xpath=".//answer/value" />
</xsd:key>
<xsd:keyref name="validAnswer" refer="answerValue">
  <xsd:selector xpath=".//response" />
  <xsd:field xpath="@questionIdRef" />
  <xsd:field xpath="." />
</xsd:keyref>

我得到的确切错误是:

字段“answer”最多需要一个值

我应该注意,我使用的是C#XML验证程序

为了完整起见,下面是我所指的完整模式和xml实例: 模式:


示例XML实例:

<?xml version="1.0" encoding="utf-8"?>
<survey>
  <user id="bob">
    <response questionIdRef="q101">yes</response>
    <response questionIdRef="q102">white</response>
  </user>
  <user id="jane">
    <response questionIdRef="q101">no</response>
    <response questionIdRef="q102">blue</response>
  </user>
  <question id="q101">
    <text>Do you like the color red?</text>
    <answer>yes</answer>
    <answer>no</answer>
  </question>
  <question id="q102">
    <text>What is your favorite color?</text>
    <answer>red</answer>
    <answer>blue</answer>
    <answer>white</answer>
    <answer>yellow</answer>
  </question>
</survey>
<?xml version="1.0" encoding="utf-8"?>
<survey>
  <user id="bob" />
  <user id="jane" />
  <question id="q101">
    <text>Do you like the color red?</text>
    <answer>yes</answer>
    <answer>no</answer>
    <response userIdRef="bob">yes</response>
    <response userIdRef="jane">no</response>
  </question>
  <question id="q102">
    <text>What is your favorite color?</text>
    <answer>red</answer>
    <answer>blue</answer>
    <answer>white</answer>
    <answer>yellow</answer>
    <response userIdRef="bob">white</response>
    <response userIdRef="jane">blue</response>
  </question>
</survey>

对
白色
不
蓝色
你喜欢红色吗?
对
不
你最喜欢什么颜色?
红色
蓝色
白色
黄色的

在您的模式中,使answer元素受枚举限制,以便在您的模式中看起来更像以下内容:

<xsd:simpleType name="answer">
    <xsd:restriction>
        <xsd:enumeration>red</xsd:enumeration>
        <xsd:enumeration>blue</xsd:enumeration>
        <xsd:enumeration>green</xsd:enumeration>
        <xsd:enumeration>yellow</xsd:enumeration>
    </xsd:restriction>
</xsd:simpleType>

红色
蓝色
绿色
黄色的

枚举限制是给定元素的一组可接受的值。

好的,我发现这个问题()与我的问题相关。这个问题也没有一个可接受的答案

这似乎是XML模式技术的一个局限性。我决定对模式进行重新排序,以将用户的响应置于问题之下。然后,响应将指向用户

下面是示例XML实例:

<?xml version="1.0" encoding="utf-8"?>
<survey>
  <user id="bob">
    <response questionIdRef="q101">yes</response>
    <response questionIdRef="q102">white</response>
  </user>
  <user id="jane">
    <response questionIdRef="q101">no</response>
    <response questionIdRef="q102">blue</response>
  </user>
  <question id="q101">
    <text>Do you like the color red?</text>
    <answer>yes</answer>
    <answer>no</answer>
  </question>
  <question id="q102">
    <text>What is your favorite color?</text>
    <answer>red</answer>
    <answer>blue</answer>
    <answer>white</answer>
    <answer>yellow</answer>
  </question>
</survey>
<?xml version="1.0" encoding="utf-8"?>
<survey>
  <user id="bob" />
  <user id="jane" />
  <question id="q101">
    <text>Do you like the color red?</text>
    <answer>yes</answer>
    <answer>no</answer>
    <response userIdRef="bob">yes</response>
    <response userIdRef="jane">no</response>
  </question>
  <question id="q102">
    <text>What is your favorite color?</text>
    <answer>red</answer>
    <answer>blue</answer>
    <answer>white</answer>
    <answer>yellow</answer>
    <response userIdRef="bob">white</response>
    <response userIdRef="jane">blue</response>
  </question>
</survey>

你喜欢红色吗?
对
不
对
不
你最喜欢什么颜色?
红色
蓝色
白色
黄色的
白色
蓝色
以下是我使用的模式:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="survey">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="user" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:attribute name="id" type="xsd:string" use="required" />
          </xsd:complexType>
        </xsd:element>
        <xsd:element name="question" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="text" type="xsd:string" />
              <xsd:element name="answer" maxOccurs="unbounded" type="xsd:string"/>
              <xsd:element name="response" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:simpleContent>
                    <xsd:extension base="xsd:string">
                      <xsd:attribute name="userIdRef" type="xsd:string" use="required" />
                    </xsd:extension>
                  </xsd:simpleContent>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
            <xsd:attribute name="id" type="xsd:string" use="required" />
          </xsd:complexType>
          <xsd:key name="validAnswerKey">
            <xsd:selector xpath=".//answer" />
            <xsd:field xpath="." />
          </xsd:key>
          <xsd:keyref name="responseValidAnswerKeyRef" refer="validAnswerKey">
            <xsd:selector xpath=".//response" />
            <xsd:field xpath="." />
          </xsd:keyref>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:key name="userIdKey">
      <xsd:selector xpath=".//user" />
      <xsd:field xpath="@id" />
    </xsd:key>
    <xsd:keyref name="userResponse" refer="userIdKey">
      <xsd:selector xpath=".//response" />
      <xsd:field xpath="@userIdRef" />
    </xsd:keyref>
  </xsd:element>
</xsd:schema>

这是我目前使用的方法。但这仍然允许响应成为不存在的答案。例如,如果颜色类型允许红色、绿色、蓝色;但问题是“你更喜欢哪个:红色还是蓝色?”xml将以“绿色”响应有效。问题在于xml包含问题和有效的回答。我希望答案只有在引用问题允许的答案时才有效。