2016-04-27 4 views
0

У меня есть аа образец XML, как следует,XSLT - помещается само текстовый узел() приписывать

<doc> 
    <para>AAAAA BBB<s/>CCC DDD<l/>EEEE<t/>FFFFF <style>GGGG</style>HHHHHH</para> 
</doc> 

с помощью XSLT Я должен преобразовать это в одном дереве узлов, но добавить имя атрибута <para> узла с именем 'name' и это значение должно быть содержанием текста элемента <para>.

Так что вывод должен быть похож,

<doc> 
    <p name="AAAAA BBB CCC DDD EEEE FFFFF GGGG HHHHHH">AAAAA BBB<s/>CCC DDD<l/>EEEE<t/>FFFFF <style>GGGG</style>HHHHHH</p> 
</doc> 

Как вы можете видеть на выходе, все текстовые узлы должны быть скопированы на значение атрибута имени и все встроенные элементы (<s/>,<t/>,<l/>,<style>) должны быть удален. и все <s/>, <t/>, <l/> необходимо заменить пробелом.

Я написал следующий XSLT для этого

<xsl:template match="p"> 
     <p name="{abc:process-attr-text(child::node())}"> 
      <xsl:apply-templates/> 
     </p> 
    </xsl:template> 

    <xsl:function name="abc:process-attr-text"> 
     <xsl:param name="node"/> 

     <xsl:sequence select="$node/text()"/> 
    </xsl:function> 

он дает следующий вывод,

<doc> 
    <p name="GGGG">AAAAA BBB<s/>CCC DDD<l/>EEEE<t/>FFFFF <style>GGGG</style> HHHHHH</p> 
</doc> 

как я могу изменить свою функцию, чтобы получить правильный результат?

ответ

4

Это немного неудобно, очевидный ответ только с помощью <p name="{.}"> не будет работать, потому что это просто конкатенации все текстовые узлы потомка, давая AAAAA BBBCCC DDDEEEEFFFFF GGGGHHHHHH

Если вы хотите обеспечить наличие пробелов везде, где есть XML-тег между соседними текстовыми узлами, тогда вам нужно быть немного более креативным. Попробуйте

<p name="{normalize-space(string-join(descendant::text(), ' '))}"> 

Это объединяет все текстовые узлы с дополнительным пространством между ними, то нормализуют раздавят два смежных пространств вниз к одному.

1

Почему не просто:

<xsl:template match="para"> 
    <p name="{.}"> 
     <xsl:apply-templates/> 
    </p> 
</xsl:template> 
Смежные вопросы