jjzjj

具有多个字段的 XML 模式键

coder 2024-07-04 原文

我有一个包含问题结构的 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 中为问题 Id 定义了一个键和一个 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>

我得到的确切错误是:

The field 'answer' is expecting at most one value.

我应该注意,我正在使用 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>

最佳答案

好的,我发现了与我的问题相关的问题 ( XSD key/keyref: hierarchical key structure)。这个问题也没有可接受的答案。

这似乎是 XML 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>

关于具有多个字段的 XML 模式键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1348753/

有关具有多个字段的 XML 模式键的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  8. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  9. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  10. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

随机推荐