2009-08-28 29 views
1

我有一個包含的問題,結構的XML文件格式:具有多個字段的XML Schema重點

<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密鑰和keyref元素爲questionId已經定義:

<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> 

我得到確切的錯誤是:

「答案」字段最多隻有一個值。

我應該注意到我正在使用C#XML驗證器。

爲了完整起見,下面是完整的架構和XML實例我指的是: 架構:

<?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:sequence> 
       <xsd:element name="response" maxOccurs="unbounded"> 
       <xsd:complexType> 
        <xsd:simpleContent> 
        <xsd:extension base="xsd:string"> 
         <xsd:attribute name="questionIdRef" 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: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:sequence> 
      <xsd:attribute name="id" type="xsd:string" use="required" /> 
      </xsd:complexType> 
      <xsd:unique name="uniqueAnswer"> 
      <xsd:selector xpath=".//answer" /> 
      <xsd:field xpath="@value" /> 
      </xsd:unique> 
     </xsd:element> 
     </xsd:sequence> 
    </xsd:complexType> 
    <!-- 

    <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> 

    --> 
    <xsd:key name="answerValue"> 
     <xsd:selector xpath=".//question" /> 
     <xsd:field xpath="@id" /> 
     <xsd:field xpath=".//answer" /> 
    </xsd:key> 
    <xsd:keyref name="validAnswer" refer="answerValue"> 
     <xsd:selector xpath=".//response" /> 
     <xsd:field xpath="@questionIdRef" /> 
     <xsd:field xpath="." /> 
    </xsd:keyref> 
    <xsd:unique name="uniqueUserId"> 
     <xsd:selector xpath=".//user" /> 
     <xsd:field xpath="@id" /> 
    </xsd:unique> 
    </xsd:element> 
</xsd:schema> 

示例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> 

回答

5

好的,我發現這個問題(XSD key/keyref: hierarchical key structure)與我的問題有關。這個問題也沒有可接受的答案。

看來這是XML Schema技術的限制。我決定對Schema重新排序,以便將用戶的回答置於該問題之下。這些迴應將會引用用戶。

下面是示例XML實例:

<?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> 
0

在您的架構使受限制的答案元素列舉,以便在您的模式中,它看起來更像以下內容:

<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> 

枚舉限制是給定元素的一組可接受的值。

+0

這是我目前使用的方法。但是,這仍然可以讓答覆成爲不存在的答案。例如,如果colorType允許紅色,綠色和藍色;但問題是「你更喜歡哪一個:紅色還是藍色?」 xml將以「綠色」響應生效。 問題是,XML包含的問題和有效的迴應。我希望響應只有在引用問題允許的答案時纔是有效的。 – Chris 2009-08-31 13:49:45