2016-11-23 5 views
2

Я думаю, мне нужна ваша помощь.Подсчет ссылок на ссылки в XSLT

У меня есть файл XML структурированы следующим образом:

<root> 
    <source id="1"/> 
    <source id="2"/> 
    <source ..... /> 
    <element id="e1"> 
     <connection from_id="1"> 
    </element> 
    <element id="e7"> 
     <connection from_id="1"> 
    </element> 
    <element id="e2"> 
     <connection from_id="e2"> 
    </element> 
    <element id="e3"> 
     <connection from_id="e2"> 
    </element> 
    <element id="e4"> 
     <connection from_id="e3"> 
    </element> 
    <element id="e5"> 
     <connection from_id="2"> 
    </element> 
    <element id="e6"> 
     <connection from_id="3"> 
    </element> 
</root> 

Теперь, что я пытался выполнить это в графа() число узлов (более конкретные: элемент-узлов), что как-то связаны с каждым источником-узлом, даже если они связаны через другой элемент. Так что для этого примера: источник-узел 1: 5 источник-узел 2: 1 источник-узел 3: 1

Если пробовали несколько подходов, в том числе функций и рекурсии, но я не был в состоянии справиться с этой задачей , С точки зрения ежедневных Java-программистов я просто пропускаю переменную или так, чтобы сохранить некоторые промежуточные результаты.

Итак, мой вопрос: как я могу это сделать без каких-либо промежуточных результатов?

+0

Вы можете иметь [рекурсивные петли] (http://stackoverflow.com/q/3709092/11683), и вы можете [хранить промежуточные результаты в переменной] (http://stackoverflow.com/a/ 3881931/11683). – GSerg

ответ

1

Первый вопрос, который вам нужно задать самому себе: есть ли необходимость в обнаружении циклов в данных или вы готовы к тому, чтобы ваша программа попала в бесконечный цикл, если существуют циклы? Обнаружение циклов затрудняет задачу, хотя ее можно добавить достаточно легко, если у вас есть базовая структура.

Далее я, возможно, неправильно понял точное требование, потому что не могу понять, как подсчет для исходного узла 1 достигает 5. Как я вижу, элементы e1 и e7 подключены к исходному узлу 1, и ни один из них не имеет любые дальнейшие соединения.

Вы не сказали, является ли это XSLT 1.0 или 2.0, но так как есть тег «Saxon» на вопрос, давайте предположим 2.0 (что будет намного проще, чем 1.0). Правильный тег здесь будет «xslt 2.0», а не «saxon», поскольку проблема не является саксонской.

Вы в основном хотите начать с функцией

<xsl:function name="f:directConnections" as="element()*"> 
    <xsl:param name="from" as="element()"/> 
    <xsl:sequence select="key('with-from-id', $from/@id, $from/root())"/> 
</xsl:function> 

заявив

<xsl:key name="with-from-id" match="connection" select="@from_id"/> 

Тогда транзитивное замыкание этой функции:

<xsl:function name="f:transitiveConnections" as="element()*"> 
    <xsl:param name="from" as="element()"/> 
    <xsl:variable name="direct" select="f:directConnections($from)"/> 
    <xsl:sequence select="$direct/(. | f:transitiveConnections(.))"/> 
</xsl:function> 

И тогда граф связей для данного узла $ N равен count(f:transitiveConnections($N)).

Все, что остается, это обнаружение цикла. Для этого добавьте дополнительный параметр в функцию, содержащую все узлы «в пути», к узлу, соединения которого вы находите, и используйте «исключение», чтобы избежать следования ссылок с любого узла, который уже «находится в пути».

<xsl:function name="f:transitiveConnections" as="element()*"> 
    <xsl:param name="from" as="element()"/> 
    <xsl:param name="enRoute" as="element()*"/> 
    <xsl:variable name="direct" 
       select="f:directConnections($from) except $enRoute"/> 
    <xsl:sequence select="$direct/(. | f:transitiveConnections(., $enRoute | .))"/> 
</xsl:function> 

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

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