2015-05-06 2 views
0

Я пытаюсь редактировать RDF/XML в XForms (реализация XSLTForms в eXist-db), и мне нужно принудительно применять различные ограничения значений для элементов с тем же именем в структурах xf:repeat. Например, у меня есть элемент bf:subject, который может принимать либо URI по умолчанию, как значение его атрибута @rdf:resource, либо произвольный URI, который ссылается на какой-либо другой ресурс, определенный в форме (для краткости я опустил их из приведенного примера ниже).Повторение XForms: одно и то же имя элемента, различные ограничения значений

В структуре xf:repeat, как я могу различать элементы с тем же именем? Я могу обработать первый сценарий с предикатом, который ограничивает значение @rdf:resource URI по умолчанию, указанному в xf:model, но я не могу найти способ добиться дифференциальной обработки для случаев, когда @rdf:resource может принимать произвольный URI.

Примечания: нет управления формы в пределах 2 вложенных хр: повторить, так как значение @rdf: ресурс обновляется динамически, используя отдельную библиотеку JavaScript (jsPlumb), который обновляет экземпляр XForms.

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet href="http://localhost:8080/exist/apps/xsltforms/xsltforms.xsl" type="text/xsl"?> 
<?xsltforms-options debug="yes"?> 
<?css-conversion no?> 
<?xml-model href="http://www.oxygenxml.com/1999/xhtml/xhtml-xforms.nvdl" schematypens="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"?> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bf="http://bibframe.org/vocab/" 
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xf="http://www.w3.org/2002/xforms" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
     <title>Editor</title> 
     <!--Model--> 
     <xf:model id="rdf-model"> 
      <xf:instance id="graph"> 
       <rdf:RDF> 
        <bf:Work rdf:about=""> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-ag"></bf:subject> 
         <bf:subject rdf:resource=""/> 
        </bf:Work> 
       </rdf:RDF> 
      </xf:instance> 
      <!-- Template --> 
      <xf:instance id="bf-Work-template"> 
       <rdf:RDF> 
        <bf:Work rdf:about=""> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-ag"></bf:subject> 
         <bf:subject rdf:resource=""/> 
        </bf:Work> 
       </rdf:RDF> 
      </xf:instance> 
     </xf:model> 
    </head> 
    <body> 
     <div id="header"> 
      <h1>Editor</h1> 
     </div> 
     <div id="forms"> 
      <!-- Repeat for Work entity --> 
      <xf:repeat nodeset="instance('graph')/bf:Work" id="repeat-Work-graph"> 

       <!-- Repeat bf:subject elements that have a default value. --> 
       <xf:repeat 
        nodeset="bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]"> 
        <div style="border:solid black 1px;"> 
         <xf:input 
          ref="@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']"> 
          <xf:label>Subject</xf:label> 
         </xf:input> 

         <!-- Add new bf:subject elements that have a default value --> 
         <xf:trigger ref="."> 
          <xf:label>+</xf:label> 
          <xf:action ev:event="DOMActivate"> 
           <xf:insert 
            nodeset="../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]" 
            origin="instance('bf-Work-template')/bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]" 
            at="last()" position="after"></xf:insert> 
          </xf:action> 
         </xf:trigger> 

         <!-- Delete bf:subject elements that have a default value --> 
         <xf:trigger 
          ref=".[count(../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]) &gt; 1]"> 
          <xf:label>-</xf:label> 
          <xf:delete ev:event="DOMActivate" nodeset="." at="last()" 
           if="count(../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]) &gt; 1" 
          ></xf:delete> 
         </xf:trigger> 
        </div> 
       </xf:repeat> 

       <!-- Add new bf:subject elements that can take an arbitrary value --> 
       <xf:trigger ref="bf:subject[@rdf:resource = '']"> 
        <xf:label>+</xf:label> 
        <xf:action ev:event="DOMActivate"> 
         <xf:insert nodeset="." 
          origin="instance('bf-Work-template')/bf:Work/bf:subject[@rdf:resource = '']" 
          at="last()" position="after"></xf:insert> 
        </xf:action> 
       </xf:trigger> 

       <!-- Delete bf:subject elements that can take an arbitrary value --> 
       <xf:trigger 
        ref="bf:subject[@rdf:resource = ''][count(../bf:subject[@rdf:resource = '']) &gt; 1]"> 
        <xf:label>-</xf:label> 
        <xf:action ev:event="DOMActivate"> 
         <xf:delete nodeset="../bf:subject[@rdf:resource = '']" at="last()" 
          if="count(../bf:subject[@rdf:resource = '']) &gt; 1"></xf:delete> 
        </xf:action> 
       </xf:trigger> 

       <!-- Repeat bf:subject elements that can take an arbitrary value --> 
       <xf:repeat nodeset="bf:subject[@rdf:resource = '']"> 
        <div style="border:solid black 1px;"> 
        <!-- Value of @rdf:resource is updated using jsPlumb library --> 
         <span class="label">Subject</span> 
         <br /> 
         <span>Link to:</span> 
         <br /> 
         <span class="connect-to">Work</span> 
         <br /> 
         <span class="connect-to">Topic</span> 
         <br /> 
         <span class="connect-to">Place</span> 
        </div> 
       </xf:repeat> 

      </xf:repeat> 
     </div> 
    </body> 
</html> 
+1

Я не буду подробно останавливаться слишком много на тему, но я укажу, что манипуляция RDF на основе XML может быть довольно подверженной ошибкам. Один и тот же график RDF может быть написан множеством разных способов с использованием RDF/XML, и данный XML-подход не будет работать на всех из них. Если возможно, лучше обработать RDF как RDF с помощью инструмента обработки RDF. См. [Мой ответ] (http://stackoverflow.com/a/17052385/1281433) на «Как получить доступ к документам OWL с использованием XPath в Java?» для некоторых примеров того, что может пойти не так. –

+0

@JoshuaTaylor, спасибо. Я понимаю, что работа с RDF/XML не идеальна, но область здесь довольно ограничена: используйте XForms для ввода данных и создайте полученный RDF/XML в triplestore. Оттуда его можно обрабатывать с помощью инструментов обработки SPARQL и RDF. Насколько мне известно, в настоящее время нет много инструментов ввода данных для создания новых данных RDF. Я знаю о [RDForms] (http://rdforms.org/#!index.md), [Графике] (https://github.com/Graphity) и [Callimachus] (http://callimachusproject.org/), но для нашего конкретного проекта нам понадобилось нечто более гибкое и настраиваемое. – tat

+0

Не могли бы вы разместить более явный тестовый пример? Я понимаю ваш вопрос как XPath, я прав? XForms 2.0 позволяет переменные, и это может упростить ваши выражения XPath. Последние сборки XSLTForms позволяют использовать var. –

ответ

1

В настоящее время идентификаторы URI по умолчанию все из того же пространства имен (http://id.loc.gov/vocabulary/...), поэтому временное решение, это просто фильтр для этого значения: not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/')). В долгосрочной перспективе я изучаю nomisma.org, который олицетворяет более устойчивый подход к управлению лексикой данных в XForms.

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet href="http://localhost:8080/exist/apps/xsltforms/xsltforms.xsl" type="text/xsl"?> 
<?xsltforms-options debug="yes"?> 
<?css-conversion no?> 
<?xml-model href="http://www.oxygenxml.com/1999/xhtml/xhtml-xforms.nvdl" schematypens="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"?> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bf="http://bibframe.org/vocab/" 
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xf="http://www.w3.org/2002/xforms" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
     <title>Editor</title> 
     <!--Model--> 
     <xf:model id="rdf-model"> 
      <xf:instance id="graph"> 
       <rdf:RDF> 
        <bf:Work rdf:about=""> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-ag"></bf:subject> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-bl"></bf:subject> 
         <bf:subject rdf:resource=""/> 
        </bf:Work> 
       </rdf:RDF> 
      </xf:instance> 
      <!-- Template --> 
      <xf:instance id="bf-Work-template"> 
       <rdf:RDF> 
        <bf:Work rdf:about=""> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-ag"></bf:subject> 
         <bf:subject rdf:resource="http://id.loc.gov/vocabulary/geographicAreas/s-bl"></bf:subject> 
         <bf:subject rdf:resource=""/> 
        </bf:Work> 
       </rdf:RDF> 
      </xf:instance> 
     </xf:model> 
    </head> 
    <body> 
     <div id="header"> 
      <h1>Editor</h1> 
     </div> 
     <div id="forms"> 
      <!-- Repeat for Work entity --> 
      <xf:repeat nodeset="instance('graph')/bf:Work" id="repeat-Work-graph"> 

       <!-- Repeat bf:subject elements that have a default value. --> 
       <xf:repeat 
        nodeset="bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]"> 
        <div style="border:solid black 1px;"> 
         <xf:input 
          ref="@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']"> 
          <xf:label>Subject</xf:label> 
         </xf:input> 

         <!-- Add new bf:subject elements that have a default value --> 
         <xf:trigger ref="."> 
          <xf:label>+</xf:label> 
          <xf:action ev:event="DOMActivate"> 
           <xf:insert 
            nodeset="../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]" 
            origin="instance('bf-Work-template')/bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]" 
            at="last()" position="after"></xf:insert> 
          </xf:action> 
         </xf:trigger> 

         <!-- Delete bf:subject elements that have a default value --> 
         <xf:trigger 
          ref=".[count(../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]) &gt; 1]"> 
          <xf:label>-</xf:label> 
          <xf:delete ev:event="DOMActivate" nodeset="." at="last()" 
           if="count(../bf:subject[@rdf:resource[. = 'http://id.loc.gov/vocabulary/geographicAreas/s-ag']]) &gt; 1" 
           ></xf:delete> 
         </xf:trigger> 
        </div> 
       </xf:repeat> 

       <!-- Add new bf:subject elements that can take an arbitrary value --> 
       <xf:trigger ref="bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]"> 
        <xf:label>+</xf:label> 
        <xf:action ev:event="DOMActivate"> 
         <xf:insert nodeset="." 
          origin="instance('bf-Work-template')/bf:Work/bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]" 
          at="last()" position="after"></xf:insert> 
        </xf:action> 
       </xf:trigger> 

       <!-- Delete bf:subject elements that can take an arbitrary value --> 
       <xf:trigger 
        ref="bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))][count(../bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]) &gt; 1]"> 
        <xf:label>-</xf:label> 
        <xf:action ev:event="DOMActivate"> 
         <xf:delete nodeset="../bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]" at="last()" 
          if="count(../bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]) &gt; 1"></xf:delete> 
        </xf:action> 
       </xf:trigger> 

       <!-- Repeat bf:subject elements that can take an arbitrary value --> 
       <xf:repeat nodeset="bf:subject[not(starts-with(@rdf:resource, 'http://id.loc.gov/vocabulary/geographicAreas/'))]"> 
        <div style="border:solid black 1px;"> 
         <!-- Value of @rdf:resource is updated using jsPlumb library --> 
         <span class="label">Subject</span> 
         <br /> 
         <span>Link to:</span> 
         <br /> 
         <span class="connect-to">Work</span> 
         <br /> 
         <span class="connect-to">Topic</span> 
         <br /> 
         <span class="connect-to">Place</span> 
        </div> 
       </xf:repeat> 

      </xf:repeat> 
     </div> 
    </body> 
</html> 
0

Если вы ищете XPath способ узнать, если элемент является первым или вторым ребенком, вы могли бы рассмотреть возможность использования осей, например, в .[preceding-sibling::bf:subject]

 Смежные вопросы

  • Нет связанных вопросов^_^