2014-05-20 47 views
3

我試圖從一個節點中刪除一個屬性,這個節點基於祖先的名字存在。如果祖先存在,XSLT刪除屬性

這是我的模板。我試圖刪除所有minOccurrs屬性,除非祖先是updateCurrentObjective

<xsl:template match="@minOccurs"> 
    <xsl:if test="0 = count(ancestor::node()[name() = 'updateCurrentObjective'])"> 
     <xsl:copy/> 
    </xsl:if> 
</xsl:template> 

因此,對於以下XML,它應該刪除該屬性。

<xs:extension base="tns:planElement"> 
    <xs:sequence> 
     <xs:element minOccurs="0" name="action" type="xs:string"/> 
    </xs:sequence> 
    <xs:extension> 

但是對於以下它應該保持不變。

<xs:complexType name="updateCurrentObjective"> 
    <xs:sequence> 
     <xs:element minOccurs="0" name="currentObjective" type="tns:objective"/> 
    </xs:sequence> 
    </xs:complexType> 

想法?

回答

3

我將有兩個模板規則:

<xsl:template match="@minOccurs"/> 

<xsl:template match="*[@name='updateCurrentObjective']//@minOccurs"> 
    <xsl:copy/> 
</xsl:template> 
1

這應該做到這一點。也可以將謂詞放在模板匹配中,但這超出了我的想象。

我也假設你正在試圖改造xsd本身(而不是匹配它的文檔的實例)

<xsl:template match="@minOccurs"> 
     <xsl:if test="parent::*[1]//ancestor::*[@name='updateCurrentObjective']"> 
      <xsl:copy/> 
    </xsl:if> 
    </xsl:template> 

基本上,從元素,追溯父元素,然後看看它的任何祖先是否有屬性name='updateCurrentObjective'。如果可以,可以使用更具體的元素名稱來代替*

2

你想操作一個模式嗎?在這種情況下,我認爲將不會有一個與name() = 'updateCurrentObjective'祖先,而將有一個與@name = 'updateCurrentObjective'元素。

所以使用

<xsl:template match="@minOccurs[not(ancestor::*[@name = 'updateCurrentObjective'])]"/> 

避免複製minOccurs屬性。