如果祖先存在,则删除XSLT属性

时间:2014-05-20 10:01:38

标签: xslt xpath

我正在尝试根据名称的祖先存在从节点中删除属性。

这是我的模板。我正在尝试删除所有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 个答案:

答案 0 :(得分:3)

我有两个模板规则:

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

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

答案 1 :(得分:2)

您想要操纵架构吗?在这种情况下,我不认为会有name() = 'updateCurrentObjective'的祖先,而是会有@name = 'updateCurrentObjective'的元素。

所以使用

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

避免复制minOccurs属性。

答案 2 :(得分:1)

这应该这样做。也可以将谓词放在模板匹配中,但这超出了我的范围。

我还假设您正在尝试转换xsd本身(而不是与之匹配的文档的实例)

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

基本上,从元素中追溯到父元素,然后查看它的任何祖先是否具有属性name='updateCurrentObjective'。如果可以,可以使用更具体的元素名称替换*