2016-11-17 2 views
1

Как я понимаю, функция xslt generate-id() вернет уникальный идентификатор в зависимости от node и его контекста (предков).xslt: contextless 'generate-id'?

Есть ли способ получить идентификатор, который зависит только от node (и его подносов), а не от его положения в документе?

При использовании xinclude идентичные узлы могут быть помещены в разные местоположения - и, следовательно, генерируются две разные идентификаторы. Как создать буквенно-цифровую строку, которая будет идентичной для каждого экземпляра набора узлов, который был вставлен в документ через xinclude?

Так у меня есть файл node.xml:

<?xml version="1.0" encoding="utf-8"?> 
<node name="joe"/> 

И в document.xml:

<?xml version="1.0" encoding="utf-8"?> 
<document xmlns:xi="http://www.w3.org/2003/XInclude"> 
    <container name="first"> 
     <xi:include href="node.xml"/> 
    </container> 
    <container name="second"> 
     <xi:include href="node.xml"/> 
    </container> 
</document> 

И в process.xslt:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="container"> 
this will not be identical for different matches of the template, although the matched <node/> has the same content: '<xsl:value-of select="generate-id(node)"/>' 
appending some attributes this is too simple, there might be differences deeper down the hierarchy, which should resolve in a different id: '<xsl:value-of select="node/@name"/>' 
</xsl:template> 
</xsl:stylesheet> 

процесса с xsltproc --xinclude process.xslt document.xml. Мне нужен один и тот же идентификатор/строка для обоих вхождений <node/>, так как они идентичны.

Приветствия

Argh. this выглядит очень похоже. Однако я не хочу вручную конкатцировать значения ...? Это не легко масштабировать в моем случае ... Может быть, я смогу что-то сделать, используя number(), но кажется, что должно быть что-то еще ...

ps: using xsltproc, так что не причудливая ...; -)

+1

Подумайте, чтобы показать нам образец ввода XML и требуемый результат. Я не понимаю, как xinclude относится к XSLT и генерирует идентификаторы. –

+0

добавлены некоторые примеры –

+0

Вы можете предварительно обработать включенный xml и поместить идентификатор на каждый узел. Затем используйте это вместо создания новых идентификаторов. Не должно быть слишком сложно? –

ответ

0

Рассмотрим следующую таблицу стилей:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xi="http://www.w3.org/2003/XInclude"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="xi:include"> 
    <xsl:variable name="node" select="document(@href)/*" /> 
    <included> 
     <id> 
      <xsl:value-of select="generate-id($node)"/> 
     </id> 
     <name> 
      <xsl:value-of select="$node/@name"/> 
     </name> 
    </included> 
</xsl:template> 

</xsl:stylesheet> 

Когда это будет применяться к входному примеру - без активации опции --xinclude - Результат будет:

<?xml version="1.0" encoding="UTF-8"?> 
<document xmlns:xi="http://www.w3.org/2003/XInclude"> 
    <container name="first"> 
    <included> 
     <id>idp944</id> 
     <name>joe</name> 
    </included> 
    </container> 
    <container name="second"> 
    <included> 
     <id>idp944</id> 
     <name>joe</name> 
    </included> 
    </container> 
</document> 

Я считаю, что, как вы пытаетесь сейчас - выполняя xinclude первые - результаты в XSLT получать объединенный документ, где каждый экземпляр включение превращается в индивидуальный набор узлов - и процессор не знает, что эти узловые наборы были едины.

1

Два элемента узла не идентичны. У них одинаковые дети/атрибуты/потомки, но у них разные родители и разные братья и сестры.

Эти два элемента узла, вероятно, имеют глубокое значение в соответствии с определением функции глубокой равности в XPath 2.0. Но глубокая спецификация - это далеко не единственный способ, которым может быть задана функция: прочитайте спецификацию, и вы увидите, что любое количество правил могло быть определено по-разному. (например, зависимости от префиксов пространства имен, текстовые узлы только для пробелов, пространственные пространства имен, базовый URI, аннотации типов).

Учитывая эти оговорки, есть случаи, когда было бы полезно иметь функцию fingerprint(node), такую ​​как fingerprint(N) = fingerprint(M), если и только если deep-equal(N, M). Вы можете написать свою собственную функцию, но ее совсем не легко написать, и она может быть неэффективной.

Таким образом, это поможет узнать, почему вы считаете, что это необходимо, потому что может быть более простой способ решить вашу проблему.

+0

будет отмечать ваш ответ как правильный, хотя это не помогает мне в данный момент ;-) это тоже выглядит многообещающе: http://stackoverflow.com/a/6754722/6884693, но xpath 2.0 –

+0

Ответ не имеет быть полезным, чтобы быть верным ... –

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