Как отобразить PCDATA между двумя пустыми тегами в один тег? - PullRequest
0 голосов
/ 23 июля 2010

У меня есть следующие сомнения в кодировании xslt.

Мой ввод: <text><p>some text</p> <p/>some text <emph>....</emph>.........<p/> </text>

И вывод, который мне нужен,

<text><p>some text</p><p>some text <emph>....</emph>.........</p></text>

Как ядолжен отображать значения, присутствующие между двумя пустыми тегами "p", в непустой тег "p"?

Ответы [ 2 ]

1 голос
/ 23 июля 2010

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="p[not(node())][last()][count(../p[not(node())]) mod 2]" priority="1">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="p[not(node())][not(position() mod 2)]" priority="1"/>
    <xsl:template match="p[not(node())]">
            <p>
                <xsl:apply-templates select="following-sibling::node()[1]"/>
            </p>
            <xsl:apply-templates select="following-sibling::p[not(node())][1]/following-sibling::node()[1]"/>
    </xsl:template>
</xsl:stylesheet>

С входами:

1 - (p с содержимым и двумя пустыми p)

<text><p>some text</p> <p/>some text <emph>....</emph>.........<p/> </text>

2 -(Четыре пустых p)

<text><p/>some text<p/> <p/>some text <emph>....</emph>.........<p/> </text>

3 - (Три пустых p)

<text><p/>some text <p/>some text <emph>....</emph>.........<p/> </text>

4 - (p с содержимым и три пустых p)

<text><p/>some text <p/>some text <p><emph>....</emph></p>.........<p/> </text>

5 - (p с содержимым два пустых p родные и другие два уровня пусто p)

<text><p>some text</p> <p/>some text <emph><p/>....<p/></emph>.........<p/> </text>

Результаты:

1 -

<text><p>some text</p><p>some text <emph>....</emph>.........</p></text>

2 -

<text><p>some text</p><p>some text <emph>....</emph>.........</p></text>

3 -

<text><p>some text </p>some text <emph>....</emph>.........<p></p></text>

4 -

<text><p>some text </p>some text <p><emph>....</emph></p>.........<p></p></text>

5 -

<text><p>some text</p><p>some text <emph><p>....</p></emph>.........</p></text>

Примечание : разбить рекурсию и следующий узел за узлом "последовательным" способом.

EDIT : Я думаю, что теперь он охватывает все случаи.Обратите внимание, что вы не можете определить в своем формате, когда у вас есть шансы p, которые из двух (предшествующих или следующих) хотят заключить.Таким образом, это «ассоциативное», оставленное до правильного.

РЕДАКТИРОВАТЬ 2 : Лучшее использование last() (Как я пропустил это?)

РЕДАКТИРОВАТЬ3 : лучшее сопоставление с образцом позволяет компактировать код.

0 голосов
/ 23 июля 2010

Это преобразование :

<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:key name="kfollowingNodes"
 match="node()[not(self::p[not(node())])]"
 use="generate-id(preceding-sibling::p[not(node())][1])"/>

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

 <xsl:template match=
 "p[not(node()) and following-sibling::p[not(node())]]">
  <xsl:variable name="vFollowing"
       select="key('kfollowingNodes', generate-id())"/>
  <xsl:if test="$vFollowing">
      <p>
       <xsl:apply-templates mode="wrap" select=
       "key('kfollowingNodes', generate-id())"/>
      </p>
  </xsl:if>
 </xsl:template>

 <xsl:template match=
 "p[not(node()) and not(following-sibling::p[not(node())])]"/>

 <xsl:template match="node()[not(self::p[not(node())])][preceding-sibling::p[not(node())]]"/>

 <xsl:template match="node()" mode="wrap">
  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

при применении к этому документу XML :

<text>
    <p>some text</p>
    <p/>some other text
    <emph>Hello World</emph>
    yet another text
    <p/>
</text>

дает желаемый результат:

<text>
    <p>some text</p>
    <p>some other text
    <emph>Hello World</emph>
    yet another text
    </p>
</text>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...