本文介绍了具有多个字段的 XML 架构键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an XML file format that contains a structure of questions:

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

我在同一个文件中也有来自多个用户的响应.

I also have in the same file responses from multiple users.

<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 定义了一个键和一个 keyref 元素:

I have already defined in the xml a key and a keyref element for the 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 执行此操作,但它只会识别第一个答案,所有其他答案均未被识别为有效:

What I would like to do now would be to do is now have the schema verify that value of the user's response for a certain question is actually an answer provided in the referenced question. I tried to do this with the following key and keyref, but it would only recognize the first answer, all other answers were not recognized as valid:

<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 验证器.

I should note that I am using C# XML validator.

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

For completeness, below is the complete schema and xml instance I am referring to:Schema:

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

推荐答案

好吧,我发现了这个问题 (XSD 密钥/keyref:分层密钥结构)与我的问题相关.这个问题也没有一个可以接受的答案.

Alright, I found this question (XSD key/keyref: hierarchical key structure) that related to my question. That question didn't have an acceptable answer either.

这似乎是 XML Schema 技术的限制.我决定重新排序架构,将用户的回答放在问题下.然后响应将指向用户.

It appears that this is a limitation of XML Schema technology. I decided to reorder the Schema, to put the user's responses under the question. The responses would then refer to the user.

以下是示例 XML 实例:

Below is the example XML Instance:

<?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 架构键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 22:32