XSLT - 如何仅保留XML中所需的元素

cc0*_*cc0 7 xml xslt xpath

我有许多包含大量开销的XML文件.我希望只保留大约20个特定元素,并过滤掉其他任何内容.我知道我想要保留的所有元素的名字,我也知道它们是否是儿童元素,谁是他们的父母.我想在转换后保留的这些元素仍然需要原始的层次结构放置.

我想继续保持

<ns:currency>

在;

<ns:stuff>
 <ns:things>
  <ns:currency>somecurrency</ns:currency>
  <ns:currency_code/>
  <ns:currency_code2/>
  <ns:currency_code3/>
  <ns:currency_code4/>
 </ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)

并使它看起来像这样;

<ns:stuff>
 <ns:things>
  <ns:currency>somecurrency</ns:currency>
 </ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)

构建XSLT来实现这一目标的最佳方法是什么?

Dim*_*hev 14

这种一般转型:

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

 <ns:WhiteList>
  <name>ns:currency</name>
  <name>ns:currency_code3</name>
 </ns:WhiteList>

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

 <xsl:template match=
  "*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当应用于提供的XML文档时(添加了命名空间定义以使其格式良好):

<ns:stuff xmlns:ns="some:ns">
    <ns:things>
        <ns:currency>somecurrency</ns:currency>
        <ns:currency_code/>
        <ns:currency_code2/>
        <ns:currency_code3/>
        <ns:currency_code4/>
    </ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)

产生想要的结果(白名单元素及其结构关系被保留):

<ns:stuff xmlns:ns="some:ns">
   <ns:things>
      <ns:currency>somecurrency</ns:currency>
      <ns:currency_code3/>
   </ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)

说明:

  1. 身份规则/模板"按原样"复制所有节点.

  2. 样式表包含一个顶级<ns:WhiteList>元素,其<name>子元素指定所有列入白名单的元素的名称 - 要在文档中保留其结构关系的元素.

  3. <ns:WhiteList>元素最好保存在单独的文档中,以便不需要使用新名称编辑当前样式表.为方便起见,白名单在同一样式表中.

  4. 一个模板覆盖了身份模板.它不处理(删除)任何未列入白名单且没有白名单后代的元素.

  • @ soulSurfer2010:每个`node()`(元素,文本,注释处理指令)和每个属性. (2认同)

Mar*_*coS 6

在XSLT中,您通常不会删除要删除的元素,但是复制要保留的元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="http://www.example.com/ns#"
    version="1.0">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

     <xsl:template match="/ns:stuff">
        <xsl:copy>
            <xsl:apply-templates select="ns:things"/>
        </xsl:copy>
     </xsl:template>

     <xsl:template match="ns:things">
        <xsl:copy>
            <xsl:apply-templates select="ns:currency"/>
            <xsl:apply-templates select="ns:currency_code3"/>                   
        </xsl:copy>
     </xsl:template>

     <xsl:template match="ns:currency">
        <xsl:copy-of select="."/>
     </xsl:template>

     <xsl:template match="ns:currency_code3">
        <xsl:copy-of select="."/>
     </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

上面的示例仅复制currencycurrency_code3.输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<ns:stuff xmlns:ns="http://www.example.com/ns#">
   <ns:things>
      <ns:currency>somecurrency</ns:currency>
      <ns:currency_code3/>
   </ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)

注意:我为您的前缀添加了名称空间声明ns.

如果要复制除少数元素之外的所有内容,您可能会看到此答案