首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT删除具有特定属性值的祖先元素。

XSLT删除具有特定属性值的祖先元素。
EN

Stack Overflow用户
提问于 2016-08-03 18:36:57
回答 2查看 837关注 0票数 0

当祖先标记(及其子标记)有空文本和特定属性值时,我尝试使用XSLT删除它们。我有XSLT来检查每个节点的text(),当它是空的并且祖先有属性deltaxml:deltaV2="A“时,我想删除祖先节点和子节点。

这里是我想要删除的xml标记(注意:祖先可以是任何东西,而不仅仅是'p')。在本例中,我希望删除最后一个p标记和子标记:

代码语言:javascript
复制
<body>
  <p deltaxml:deltaV2="A=B">
    <t>This is the same</t>
  </p>
  <p deltaxml:deltaV2="B">
    <t>This is inserted</t>
  </p>
  <p deltaxml:deltaV2="A">
    <t>This is deleted</t>
  </p>
  <p deltaxml:deltaV2="A">
    <t> </t>
  </p>
</body>

下面是我到目前为止拥有的XSLT:

代码语言:javascript
复制
<xsl:template match="@* | * | processing-instruction() | comment()" mode="#all">
  <xsl:copy copy-namespaces="no">
    <xsl:apply-templates select="@*, node()" mode="#current"/>
  </xsl:copy>
</xsl:template> 
<xsl:template match="text()">
   <xsl:variable name="deltaV2" as="attribute()" select="ancestor::*[@deltaxml:deltaV2][1]/@deltaxml:deltaV2"/>
   <xsl:variable name="text" select="."/>
<xsl:choose>
  <xsl:when test="$deltaV2 eq 'A'">
    <xsl:choose>
      <xsl:when test="$text = ' '">

        <!-- need to remove ancestor tags-->

      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="delete" namespace="{$root-ns}">
          <xsl:value-of select="."/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:when>
  <xsl:when test="$deltaV2 eq 'B'">
    <xsl:element name="insert" namespace="{$root-ns}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="."/>
  </xsl:otherwise>
</xsl:choose>

以下是所需的输出:

代码语言:javascript
复制
<body>
  <p deltaxml:deltaV2="A=B">
    <t>This is the same</t>
  </p>
  <p deltaxml:deltaV2="B">
    <t><insert>This is inserted</insert></t>
  </p>
  <p deltaxml:deltaV2="A">
    <t><delete>This is deleted</delete></t>
  </p>
</body>

我之所以需要这样做,是因为这些属性显示了XML的两个版本之间是否插入或删除了某个内容,但是如果存在一个空节点(即。(示例中的空t标记)我不想将其作为一个更改来跟踪,因为没有任何文本更改,而只是希望将其删除。当文本为空以便能够删除这些标记时,我需要放什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-03 19:40:22

我试图使用XSLT删除..。当标记有空文本和特定属性值时(以及它们的子标记)。

这样做的模板非常简单。

代码语言:javascript
复制
<xsl:template match="*[@deltaxml:deltaV2 = 'A' and normalize-space() = '']" />

将其与身份转换一起使用。在这里阅读身份转换:http://www.dpawson.co.uk/xsl/sect2/identity.html (你最喜欢的搜索引擎会提供的其他无数例子)。

这里的这个问题还为您描述的同一个问题提供了一个规范的答案:How to remove elements from xml using xslt with stylesheet and xsltproc?

票数 1
EN

Stack Overflow用户

发布于 2016-08-03 21:02:02

不能在处理后代的模板中移除祖先。当样式表到达空的text()节点时,p祖先已经被处理并写入输出树-请参阅:https://www.w3.org/TR/xslt/#section-Processing-Model

如果您将需求重声明为:删除满足这两种要求的任何元素(及其所有后代):

  1. 具有一个名为deltaxml:deltaV2的属性,其值为"A";
  2. 具有至少一个子代元素,没有非空白文本节点,

然后,您可以将其实现为:

代码语言:javascript
复制
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:deltaxml="http://example.com/deltaxml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="*[@deltaxml:deltaV2='A'][.//*[not(normalize-space())]]" />

</xsl:stylesheet>

当然,您需要将deltaxml:前缀绑定到输入XML中使用的同一个命名空间URI,而不是像我在这里所做的那样任意绑定。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38751266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档