2014-02-15 4 views
0

Я пытаюсь подсчитать количество совпадений конкретных людей внутри записей событий в XML-документе. Мой исходный документ состоит из элементов событий, которые содержат прозу в p-элементах и ​​библиографических записях в элементах bibl, которые содержат ссылки на людей. Я хотел бы иметь возможность подсчитать, как часто два человека появляются в событиях во всем документе. Я использую XSLT 2.0, но могу переключиться на 3.0.XSLT для подсчета совпадений особых дочерних элементов

(как, например, я могу получить ответ 3 на количество раз, что Нэнси Дрю и Дик Трейси находятся в мероприятиях вместе ниже? Или 1 для Дика Трейси и Sam Spade?)

<listEvent> 
     <event xml:id="e1"> 
      <p>pretium eget erat eu cursus. Duis pulvinar lectus sed quam vehicula tincidunt in 
       vel nunc. Cras convallis elementum diam. Sed nec viverra magna. Then <name 
       SameAs="detectives.xml#ND">Nancy Drew</name> solved the case. A consequat 
       tortor molestie ut. Praesent lobortis ipsum sit amet bibendum consequat. </p> 

      <bibl><name SameAs="detectives.xml#DT">Tracy, Dick</name>. The Mysterious Case of the 
       Orange Fish. Penguin Publishing. </bibl> 
      <bibl><name SameAs="detectives.xml#SH">Holmes, Sherlock</name>. The Case of the Blue 
       Carbuncle Penguin Publishing. </bibl> 

     </event> 
     <event xml:id="e2"> 
      <p> facilisis turpis eu, gravida enim. Mauris adipiscing magna consequat dolor 
       auctor, sit amet tincidunt felis auctor. <name SameAs="detectives.xml#ND">Nancy 
       Drew</name> and <name SameAs="detectives.xml#DT">Dick Tracy</name> went into 
       business together. Aliquam pharetra semper erat, at viverra tellus vestibulum 
       quis. Sed facilisis convallis justo, suscipit fermentum lorem egestas nec. 
       Phasellus in aliquam eros, vitae fringilla augue </p> 

      <bibl><name SameAs="detectives.xml#TH">Hardy, Tom</name>. Growing Up Is Hard to Do: 
       The Story of a Boy Detective. Knopf Press. </bibl> 
      <bibl><name SameAs="detectives.xml#SH">Holmes, Sherlock</name>. The Case of the Blue 
       Carbuncle. Penguin Publishing. </bibl> 
      <bibl><name SameAs="detectives.xml#SH">Holmes, Sherlock</name>. The Hound of the 
       Baskervilles. Arsenal Press. </bibl> 

     </event> 
     <event xml:id="e3"> 
      <p> Curabitur dapibus eu ligula sed elementum. Curabitur sit amet nisi dictum. <name 
       SameAs="detectives.xml#SS">Sam Spade</name> was the only detective in town. 
       Donec cursus diam sem, astor. </p> 

      <bibl><name SameAs="detectives.xml#TH">Hardy, Tom</name>. Growing Up Is Hard to Do: 
       The Story of a Boy Detective. Knopf Press. </bibl> 
      <bibl><name SameAs="detectives.xml#SS">Spade, Sam</name>. My Friends' Business 
       Ventures. Knopf Press. </bibl> 
      <bibl><name SameAs="detectives.xml#DN">Drew, Nancy</name>. Blonde and Curious. 
       Arsenal Press.</bibl> 

     </event> 
     <event xml:id="e4"> 
      <p> Duis pulvinar lectus sed quam vehicula tincidunt in vel nunc. <name 
       SameAs="detectives.xml#ND">Nancy Drew</name> and <name 
       SameAs="detectives.xml#DT">Dick Tracy</name> made 110% profit that year. Cras 
       convallis elementum diam. Sed nec viverra magna. A consequat tortor molestie ut. 
       Praesent lobortis ipsum sit amet bibendum consequat. </p> 

      <bibl><name SameAs="detectives.xml#SS">Spade, Sam</name>. My Friends' Business 
       Ventures. Knopf Press. </bibl> 
      <bibl><name SameAs="detectives.xml#MH">Holmes, Mycroft</name>. Sons and Brothers. 
       Knopf Press. </bibl> 
     </event> 
    </listEvent> 

@ michael.hor257k Мне нравится ваше мышление. Я надеюсь получить вывод, который выглядит следующим образом:

<gexf> <graph><nodes count="77"> 
<node id="1.0" label="Sam Spade"/> 
<node id="2.0" label="Dick Tracy"/> 
<node id="3.0" label="Nancy Drew"/> 
… 
</nodes> 

<edges count="254"> 
<edge id="1" source="1.0" target="2.0" weight="1.0"/> 
<edge id="2" source="1.0" target="3.0" weight="2.0"/> 
<edge id="3" source="2.0" target="3.0" weight="3.0"/> 
… 
</edges> 
</graph> 
</gexf> 

... где значение @weight является то, что у меня возникают проблемы вычислений.

Мне удалось назначить каждому человеку узел @id. Узел @ids затем составляет значения @source и @target (первый - Сэм Спейд и Дик Трейси, второй Сэм Спейд и Нэнси Дрю), а @weight должно быть количеством раз, когда они появляются вместе в документе (Я, возможно, ... возможно, упростил мой пример. В моем фактическом исходном документе есть несколько других атрибутов и значений в каждом элементе, включая @n для имени каждого человека, поэтому используйте значение-select для заполнения @ ids, @sources и @target были быстрыми).

@tim, не беспокойтесь, @SameAs указывает на список полномочий, так что независимо от того, как имя человека записано в тексте (то есть, Люси, мисс Грэхем и миссис Л. Фостер могли бы все быть именами в тексте для той же женщины, что и девочка, до того, как она вышла замуж и после нее, или наоборот, как это делается в библиографической записи), ее можно решить одним человеком.

+0

ли вы имеете в виду вы хотите, чтобы изучить все возможные комбинации двух имен? Возможно, вам следует опубликовать пример того, как должен выглядеть вывод, по коду. –

+0

У вас в вашем XML есть «Нэнси Дрю» и «Дрю, Нэнси». Вы ожидали бы, что к ним будут относиться как к другим именам? (Атрибут @SameAs отличается для них тоже). –

+0

@ michael.hor257k Мне нравится ваше мышление.Результат должен выглядеть так: ' ... <края считаются = "254"> <край ID = "1" источник = "1.0" целевых = "2.0" вес = "1.0" /> ... /gefx> ' – CLKC

ответ

0

не волнуйтесь, в @SameAs пункты к списку полномочий

Ну, дело в том, что находитесь в XSLT живет за счет того, что находится в исходном XML-документа - так необходимые отсчеты здесь будет до различные значения @SameAs разрешены.

В моем фактическом источнике доке есть куча других атрибутов и значений в каждом элементе, в том числе @n для имени каждого человека

Хорошо, так как мы не имеем, что, Я использовал атрибут @SameAs, как если бы это был отдельный идентификатор. На самом деле это таблица стилей XSLT 1.0, дополненная функцией EXSLT set: distinct(). Это всего лишь эскиз с оставленными лесами, поэтому мы можем видеть, движется ли это в правильном направлении.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:set="http://exslt.org/sets" 
extension-element-prefixes="set"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:key name="eventByID" match="event" use=".//name/@SameAs" /> 

<xsl:variable name="distinct_nodes" select="set:distinct(/listEvent/event//name/@SameAs)" /> 
<xsl:variable name="root" select="/" /> 

<xsl:template match="/"> 
<graph> 
    <nodes> 
     <xsl:for-each select="$distinct_nodes"> 
      <node id="{.}"/> 
     </xsl:for-each> 
    </nodes> 
    <edges> 
     <xsl:for-each select="$distinct_nodes[not(position()=last())]"> 
      <xsl:variable name="source" select="." /> 
      <xsl:variable name="pos" select="position()" /> 
       <xsl:for-each select="$distinct_nodes[position()>$pos]"> 
        <xsl:variable name="target" select="." /> 
        <xsl:variable name="common_events" select="key('eventByID', $source)[@xml:id=key('eventByID', $target)/@xml:id]" /> 
        <xsl:if test="$common_events"> 
         <edge source="{$source}" target="{$target}" weight="{count($common_events)}"> 
         <!-- use this for test purposes --> 
          <!-- 
          <xsl:for-each select="$common_events"> 
           <event id="{@xml:id}"/> 
          </xsl:for-each> 
          --> 
         </edge> 
        </xsl:if> 
       </xsl:for-each> 
     </xsl:for-each> 
    </edges> 
</graph> 
</xsl:template> 
</xsl:stylesheet> 

Применительно к вашему примеру XML, результат:

<?xml version="1.0" encoding="utf-8"?> 
<graph> 
    <nodes> 
     <node id="detectives.xml#ND"/> 
     <node id="detectives.xml#DT"/> 
     <node id="detectives.xml#SH"/> 
     <node id="detectives.xml#TH"/> 
     <node id="detectives.xml#SS"/> 
     <node id="detectives.xml#DN"/> 
     <node id="detectives.xml#MH"/> 
    </nodes> 
    <edges> 
     <edge source="detectives.xml#ND" target="detectives.xml#DT" weight="3"/> 
     <edge source="detectives.xml#ND" target="detectives.xml#SH" weight="2"/> 
     <edge source="detectives.xml#ND" target="detectives.xml#TH" weight="1"/> 
     <edge source="detectives.xml#ND" target="detectives.xml#SS" weight="1"/> 
     <edge source="detectives.xml#ND" target="detectives.xml#MH" weight="1"/> 
     <edge source="detectives.xml#DT" target="detectives.xml#SH" weight="2"/> 
     <edge source="detectives.xml#DT" target="detectives.xml#TH" weight="1"/> 
     <edge source="detectives.xml#DT" target="detectives.xml#SS" weight="1"/> 
     <edge source="detectives.xml#DT" target="detectives.xml#MH" weight="1"/> 
     <edge source="detectives.xml#SH" target="detectives.xml#TH" weight="1"/> 
     <edge source="detectives.xml#TH" target="detectives.xml#SS" weight="1"/> 
     <edge source="detectives.xml#TH" target="detectives.xml#DN" weight="1"/> 
     <edge source="detectives.xml#SS" target="detectives.xml#DN" weight="1"/> 
     <edge source="detectives.xml#SS" target="detectives.xml#MH" weight="1"/> 
    </edges> 
</graph> 
+0

Я никогда не пробовал EXSLT раньше. @ michael.hor257k ваш результат * точно * то, что я ищу, но я, когда я пробую листок, получаю фатальную ошибку от Saxon-EE 9.5.1.3 «XTDE1425: не удается найти подходящую функцию с одним аргументом с именем { http://exslt.org/sets} distinct() ", хотя пространство имен sets выглядит идеально. Я пробовал Saxon 6.5.5 и Xalan, который завершит преобразование, но вернет пустые узловые и графические элементы. Я правильно диагностирую это? Я использую неправильные процессоры? – CLKC

+0

@CLKC Он отлично работает как в [Saxon 6.5.5] (http://xsltransform.net/3Nqn5Ya), так и в [Xalan 2.7.1] (http://xsltransform.net/3Nqn5Ya/1). В XSLT 2.0, я полагаю, вам нужно написать свой собственный: http://www.w3.org/TR/xpath-functions/#func-distinct-nodes-stable –

+0

Что-то вроде [this] (http: // xsltransform. net/3Nqn5Ya/2), я думаю; вероятно, некоторые упрощения могут быть сделаны при использовании процессора XSLT 2.0. –

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