2016-02-25 45 views
1

我在我的XSLT書中找不到像這樣的例子,但是,我真的不知道該找什麼。我試着用Google搜索,但我真的不知道如何制定搜索條件。我試圖根據父母對待<p>節點。這是我的xml,非常簡化。XSLT:只應用多個匹配模板中的一個?

<body> 
    <p>consequuntur magni dolores eos</p>  <!-- Needs one LF --> 
    <p>numquam eius modi tempora</p>    <!-- Needs two LFs --> 
    <ul> 
    <li><p>aliquam quaerat voluptatem</p></li> <!-- Needs one LF --> 
    <li><p>quis nostrum</p></li>    <!-- Needs two LFs --> 
    </ul> 
    <some><arbitrary><path><p>qui dolorem ipsum</p></path></arbitrary></some> 
</body> 

我做的只是罰款與非任意<p>節點:

<xsl:template match="body/p[1] | li/p[1]"> 
    <xsl:text>&#10;</xsl:text> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="body/p[position() > 1] | li/p[position() > 1]"> 
    <xsl:text>&#10;&#10;</xsl:text> 
    <xsl:apply-templates/> 
</xsl:template> 

但我也需要任意<p>一個模板,而這也正是我惹上麻煩:<xsl:template match="p">得到應用到身體和li <p>節點也。

看來最直接的方法是以某種方式讓處理器不要將任意<p>應用於所有東西,但我無法弄清楚如何做到這一點。我想也許可以在我的任意模板中添加*[not(self::body)]/p | *[not(self::li)]/p之類的東西,但這是一個聯盟,我無法弄清楚如何獲得交集。我已經看到了一些方法,包括邁克爾凱的方法,但我無法理解符號,無論如何,我不確定這是做到最好(正確)的方法。

回答

2

選擇除了那些的bodyli元件直接子可以由單個謂詞來實現所有p元素。

* [not(self :: body)]/p | * [不(個體經營::李)]/P

相當接近,但|是不是還是運營商,而是正如你所指出的聯合。因此,選擇所有p元素並檢查它們是否不是body的孩子,而不是li的孩子成功。

<xsl:template match="p[not(../../body) and not(../../li)]"> 
    <xsl:text>...</xsl:text> 
    <xsl:apply-templates/> 
</xsl:template> 

應用的DeMorgan這可以簡化爲

<xsl:template match="p[not(../../body or ../../li)]"> 
    <xsl:text>...</xsl:text> 
    <xsl:apply-templates/> 
</xsl:template> 
2

您可能正在尋找priority屬性。你可以例如使用

<xsl:template match="p" priority="1"> 

<xsl:template match="body/p[1] | li/p[1]" priority="2"> 

<xsl:template match="body/p[position() > 1] | li/p[position() > 1]" priority="2">