如果子节点之一具有特定上下文,则使用xslt更改父元素

时间:2018-08-02 09:54:19

标签: xml xslt xpath transform

我有以下XML:

<vce>
<document url="https://amdocssandbox.service-now.com/aps/? 
table=sn_customerservice_aps_and_optima_cases&sys_id=300384- 
040406&id=aps_case_details" vse-key-normalized="vse-key-normalized">
<content name="Knowledge_Item_type" type="text">Case</content>
<content name="Knowledge_item_ID" type="text" name-original="Case_ID">300384- 
040406</content>
<content name="PSP_update_dt" type="text" name- 
original="PSP_Case_update_dt">1900-01-01 00:00:00.0000000</content>
<content name="Item_URL_internal" type="text" name- 
original="Case_URL_internal">
https://amdocssandbox.service-now.com/aps/? 
table=sn_customerservice_aps_and_optima_cases&sys_id=300384- 
040406&id=aps_case_details
</content>
<content name="Item_URL_external" type="text" name- 
original="Case_URL_external">
https://amdocssandbox.service-now.com/aps/? 
table=sn_customerservice_aps_and_optima_cases&sys_id=300384- 
040406&id=aps_case_details
</content>
<content name="Product_tree" type="text">^ > ^ > ^ > ^</content>
<content name="User_type" type="text" action="none">n/a</content>
<content name="Last_updated_date" type="text">2017-07-27 
08:32:56.0000000</content>
<content name="Sort_Date" type="text" action="none">1501133576</content>
<content name="Knowledge_item_name" type="text" name- 
original="Case_title">Unable to write Statistics when Gatherer</content>
<content name="instacne_ID" type="text" name- 
original="Instance_ID">f52ec8d04f5c43000aa036e18110c771</content>
<content name="Business_line" type="text" name- 
original="business_line">APS</content>
 </document>
</vce>

我的目标是在某些内容等于某个值的情况下将此XML转换为空。 例如if content[@name = 'Knowledge_item_ID'] /text() = '300384- 040406',而不是我想清空所有其他内容的值,即:

<vce>
 <document>
   <content/>
   <content/> 
      .
      .
      .
   <content/>
 <document/>
</vce>

我对XSLT还是很陌生,并且不确定内部节点是否具有特定值时如何清空所有节点。

谢谢!

1 个答案:

答案 0 :(得分:0)

首先请注意,您的XML格式不正确,因为您在某些需要转义的属性中使用了& ...

<document url="https://amdocssandbox.service-now.com/aps/?table=sn_customerservice_aps_and_optima_cases&amp;sys_id=300384-040406&amp;id=aps_case_details" ...

(属性名称中也有换行符,这也会引起问题)

但是假设您拥有格式正确的XML,那么您想要的表达式就是这个

<xsl:template match="*[content[@name='Knowledge_item_ID'] = '300384-040406']/content">

在此模板中,您将只创建一个空的content元素。

这将与身份模板一起用于处理其他任何元素

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" />

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

  <xsl:template match="*[content[@name='Knowledge_item_ID'] = '300384-040406']/content">
    <xsl:copy />
  </xsl:template>
</xsl:stylesheet>

请参见http://xsltfiddle.liberty-development.net/jyH9rMw

编辑:为回答您的评论,如果您实际上想删除document元素,而只保留vce元素,请尝试

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" />

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

  <xsl:template match="document[content[@name='Knowledge_item_ID'] = '300384-040406']" />

</xsl:stylesheet>

在此解决方案中,第一个模板是身份模板,该模板只是在未更改的情况下跨节点复制。

具有更高优先级的第二个模板,因此将首先匹配,将匹配包含document个元素(其中“ Knowledge_item_ID”等于“ 300384-040406”)的content个元素。在这种情况下,模板不会执行任何操作,因此不会将document元素复制到输出中。

如果document元素没有匹配的“ Knowledge_item_ID”,则只有身份模板会与之匹配,然后将其不变地复制。

请参见http://xsltfiddle.liberty-development.net/jyH9rMw/1