XSLT 查找所有相关元素

XSLT to find all related elements

我正在尝试确定是否可以使用 XSLT 来转换以下 XML(代码段,因为它包含更多元素),以便转换后的 XML 仅包含以下内容元素在子元素中指定。

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <content content-id="a">
        <content-link content-id="a1"/>
        <content-link content-id="a2"/>
    </content>
    <content content-id="b">
        <content-link content-id="b1"/>
        <content-link content-id="b2"/>
    </content>
    <content content-id="a1">
        <content-link content-id="a11"/>
        <content-link content-id="a12"/>
    </content>
    <content content-id="a2">
        <content-link content-id="a21"/>
        <content-link content-id="a22"/>
    </content>
    <content content-id="a11"/>
    <content content-id="a12"/>
    <content content-id="a21"/>
    <content content-id="a22"/>    
</library>

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <content content-id="a">
        <content-link content-id="a1"/>
        <content-link content-id="a2"/>
    </content>
    <content content-id="a1">
        <content-link content-id="a11"/>
        <content-link content-id="a12"/>
    </content>
    <content content-id="a2">
        <content-link content-id="a21"/>
        <content-link content-id="a22"/>
    </content>
    <content content-id="a11"/>
    <content content-id="a12"/>
    <content content-id="a21"/>
    <content content-id="a22"/>    
</library>

以下是我的尝试,但我在 XSLT 方面相当薄弱,因此感谢您在这里提供进一步的意见

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   
    <xsl:output method="xml" indent="yes"/>
    <xsl:variable name="cid" select="'a'" />
    <xsl:template match="/">
        <library>        
        <xsl:apply-templates select="//content[@content-id=$cid]"/>        
        </library>
    </xsl:template>
    
    <xsl:template match="content">        
        <xsl:copy-of select="." />        
        <xsl:for-each select="*">
            <xsl:apply-templates select="content-link"/>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match="content-link">
         <!-- Don't know how to call the ancestor content elements referenced by content-link -->
    </xsl:template>
</xsl:stylesheet>

大概是这样的:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">
    
  <xsl:function name="mf:get-related-elements" as="element()*">
      <xsl:param name="element" as="element()"/>
      <xsl:sequence
        select="$element ! (. | content-link | key('ref', content-link/@content-id)/mf:get-related-elements(.))"/>
  </xsl:function>
  
  <xsl:key name="ref" match="/*//*" use="@content-id"/>
    
  <xsl:param name="cid" select="'a'" />
  
  <xsl:variable name="start" select="key('ref', $cid)"/>
  <xsl:variable name="related-elements" select="mf:get-related-elements($start)"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/*//*[not(. intersect $related-elements)]"/>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6q1SDjU