XSLT删除属于命名空间的标记/属性

Ind*_*ian 10 xslt

我正在尝试使用XSLT删除属于命名空间的标签/属性.困难在于来自不同名称空间的标签可以相互嵌入.

样品:

<?xml version="1.0" encoding="utf-8"?>
<Collection xmlns="http://s0" xmlns:ns1="http://s1">
  <Identifier Name="CollectionX"
          ns1:GlobalID="{E436833B-B0A6-4E0D-804B-60052B767AE3}"
          ns1:LocalID="{0130C866-7A91-4544-A82B-E0C0F2E3BCB2}"  />

  <Properties>
    <ns1:Collectible>1982</ns1:Collectible>
    <Displayed>Reserved</Displayed>
    <Picture>Reserved.jpeg</Picture>
  </Properties>

  <WeakLinks>
    <Link Type="resource" Language="en-us"/>
  </WeakLinks>

</Collection>
Run Code Online (Sandbox Code Playgroud)

我想过滤所有不属于ns1的标签/属性,只要它们没有任何ns1子级.

所以结果应该是:

<?xml version="1.0" encoding="utf-8"?>
<Collection xmlns="http://s0" xmlns:ns1="http://s1">
  <Identifier 
      ns1:GlobalID="{E436833B-B0A6-4E0D-804B-60052B767AE3}"
      ns1:LocalID="{0130C866-7A91-4544-A82B-E0C0F2E3BCB2}"  />

  <Properties>
    <ns1:Collectible>1982</ns1:Collectible>
  </Properties>

</Collection>
Run Code Online (Sandbox Code Playgroud)

我怎样才能用XSLT来解决这个问题?有帮助吗?

Dim*_*hev 6

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns1="http://s1">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
 "*[not(attribute::ns1:*)
  and
    not(descendant-or-self::ns1:*)
   ]
 |
  @*[not(namespace-uri()='http://s1')]
 "/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当应用于提供的XML文档时:

<Collection xmlns="http://s0" xmlns:ns1="http://s1">
    <Identifier Name="CollectionX"
      ns1:GlobalID="{E436833B-B0A6-4E0D-804B-60052B767AE3}"
      ns1:LocalID="{0130C866-7A91-4544-A82B-E0C0F2E3BCB2}"  />
    <Properties>
        <ns1:Collectible>1982</ns1:Collectible>
        <Displayed>Reserved</Displayed>
        <Picture>Reserved.jpeg</Picture>
    </Properties>
    <WeakLinks>
        <Link Type="resource" Language="en-us"/>
    </WeakLinks>
</Collection>
Run Code Online (Sandbox Code Playgroud)

产生想要的,正确的结果:

<Collection xmlns="http://s0" xmlns:ns1="http://s1">
   <Identifier ns1:GlobalID="{E436833B-B0A6-4E0D-804B-60052B767AE3}"
   ns1:LocalID="{0130C866-7A91-4544-A82B-E0C0F2E3BCB2}"/>
   <Properties>
      <ns1:Collectible>1982</ns1:Collectible>
   </Properties>
</Collection>
Run Code Online (Sandbox Code Playgroud)

说明:

  1. 身份规则(模板)"按原样 " 复制每个节点.

  2. 只有一个模板覆盖了身份规则.此模板没有正文 - 这意味着它可以有效地过滤(删除)任何匹配的节点,使其不被复制到输出.匹配的节点正是必须过滤掉的节点:1)任何不具有属于ns1:绑定前缀的命名空间的属性的元素,也不属于该命名空间,也没有后代元素属于该命名空间的节点.2)任何不属于该命名空间的属性.

请记住:覆盖标识规则是最基本和最强大的XSLT设计模式.有关此设计模式的更多信息,请参见此处.