XSLT, как получать и выводить комбинированные элементы - PullRequest
4 голосов
/ 22 апреля 2011

Уважаемое сообщество, было бы здорово, если бы вы могли дать мне совет, как это преобразовать:

<div>  
something  
   <title>   this title  </title>  
    something else  
</div>  

в

<div>  
<title1>
something  </title1>  
<title2>  this title  </title2>  
<title3>  something else  </title>
</div>

К сожалению, метод substring-before / after нельзя использовать, так как внутри div есть внутренний элемент. Более того, похоже, что copy-of не работает с подстрокой. Есть ли у вас какие-либо советы о том, как преобразовать вышеуказанный XML?

Ответы [ 3 ]

3 голосов
/ 22 апреля 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="div/text()|div/*">
        <xsl:element name="title{position()}">
            <xsl:value-of select="normalize-space(self::text())"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<div>
    <title1>something</title1>
    <title2> this title </title2>
    <title3>something else</title3>
</div>
1 голос
/ 23 апреля 2011

Это решение является несколько более точным и более общим одновременно :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="/*/node()">
  <xsl:element name="title{position()}">
   <xsl:copy-of select="translate(self::text()|node(), '&#xA;&#xD;', '  ')"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

При применении к предоставленному документу XML :

<div>
something      
    <title>   this title  </title>
     something else
</div>

получается более приближенный к желаемому результату (только символы NL или CR преобразуются в пробел):

<div>
   <title1> something           </title1>
   <title2>   this title  </title2>
   <title3>      something else </title3>
</div>
0 голосов
/ 22 апреля 2011

Редактировать

Я только что понял, что мой вывод не совпадает с вашим.Но решение @ Alejandro идеально, так что я надеюсь, что вы не будете слишком расстроены этим.


Я придумал это решение:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xsl:element name="div">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="div/text()|div/title/text()">
        <xsl:element name="title{position()}">
            <xsl:copy-of select="normalize-space(.)" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

, которое производит такой вывод:

<?xml version="1.0" encoding="UTF-8"?>
<div>
    <title1>something</title1>
    <title1>this title</title1>
    <title3>something else</title3>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...