xpath 1.0 список узлов, ссылающихся на текущий узел (подсчет ссылок)

Что я пытаюсь сделать:

Я хотел бы найти правильный xpath для подсчета (или списка) ссылок, относящихся к активному узлу.

мой контекст - это javascript со следующим отдельным деревом dom, используемым для запроса xpath с document.evaluate, дающим конкретную точку входа.

В качестве примера рассмотрим //*[@id="n11"] как точку входа или активный узел (второй параметр document.evaluate)

здесь отдельно стоящее дерево:

<root>
    <node>
        <a id="n1"/>
        <a id="n2"/>
        <a id="n3"/>
        <a id="n4"/>
        <a id="n5"/>
        <a id="n10"/>
        <a id="n11"/>
        <a id="n12"/>
    </node>
    <link>
        <a><source>n1</source><target>n2</target></a>
        <a><source>n1</source><target>n11</target></a>
        <a><source>n11</source><target>n3</target></a>
        <a><source>n5</source><target>n5</target></a>
    </link>
</root>

Я пробовал несколько вещей, но ни один из них не дал ожидаемого результата:

  • узлы без ссылки: /node/*[not(@id = /link/*/source | /link/*/target)]

  • узлы с одной ссылкой: /node/*[@id = /link/*[not(target = following::source | following::target | preceding::source | preceding::target)]/target] | /node/*[@id = /link/*[not(source = following::source | following::target | preceding::source | preceding::target)]/source]

  • узлы с более чем одной связью /node/*[@id = /link/*[target = following::source | following::target | preceding::source | preceding::target]/target] | /node/*[@id = /link/*[source = following::source | following::target | preceding::source | preceding::target]/source]

но тезисы не дают мне номер ссылки для текущего узла.

это не работает : count(./[@id = /link/*[target | source]])

это не лучше: count(/link/*[current()/@id = target | source]]) потому что текущий существует в контексте xslt, а не только в контексте xpath.

Есть ли способ xpath?

два других способа, о которых я думаю, это: переработка моего дерева домов, чтобы сгладить его, как это:

<root>
    <node id="n1"/>
    <node id="n2"/>
    <node id="n3"/>
    <node id="n4"/>
    <node id="n5"/>
    <node id="n10"/>
    <node id="n11"/>
    <node id="n12"/>
    <link source="n1" target="n2"/>
    <link source="n1" target="n11"/>
    <link source="n11" target="n3"/>
    <link source="n5" target="n5"/>
</root>

но с первым деревом dom я могу преобразовать любой json в dom и запросить его с помощью xpath, во втором дереве dom я больше зависим от структуры данных.

Другой способ, который я вижу, - это сделать рекурсивный xpath, подобный этому (на первом дереве дома): count(/link/*[target | source = {concat('"',@id,'"')}]]) и в javascript, ищущий вложенный xpath, оценивать их, заменяя их там родительским и оценивая родительский xpath. Здесь это может помочь, но будет сложнее справиться, когда вложенный xpath возвращает набор узлов, а не строку.

Наконец, почему я пытаюсь это сделать? для этого проекта: https://github.com/1twitif/social-viz Я хочу предоставить мощность xpath пользователю, которому нужна расширенная конфигурация, но не предоставить им всю мощь javascript для фильтрации данных, чтобы избежать xss при оценке ненадежного сценария js пользователя.


person 1000i100    schedule 20.02.2017    source источник
comment
stackoverflow.com/questions/35850586/ заставляет меня думать, что для этого нет способа xpath-1.0:/   -  person 1000i100    schedule 20.02.2017
comment
Для первого предоставленного вами XML для выбора узлов без ссылки работает ли этот xpath? /root/node/*[not(@id = /root/link/*/*)]   -  person Lingamurthy CS    schedule 20.02.2017
comment
да, вот так: /node/*[not(@id = /link/*/source | /link/*/target)] (с /root для xpath explorer, без для document.evaluate).   -  person 1000i100    schedule 21.02.2017