Xml 查找所有相关元素的XSLT

Xml 查找所有相关元素的XSLT,xml,xslt,xslt-1.0,xslt-2.0,xslt-3.0,Xml,Xslt,Xslt 1.0,Xslt 2.0,Xslt 3.0,我试图找出是否可以使用XSLT转换以下XML(代码段,因为它包含更多元素),以便转换后的XML只包含在子元素中指定的内容元素 <?xml version="1.0" encoding="UTF-8"?> <library> <content content-id="a"> <content-link content-id="a1"/>

我试图找出是否可以使用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>


下面是我的尝试,但我在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>


请详细解释此处需要应用的逻辑。感谢Martin,您的XSLT绝对有帮助!我刚刚意识到我的内容链接元素是一个孙子,如下面的示例片段所示:但是我没有足够的技能进行正确的更改,因此不知道您是否可以在这里提供帮助。我设法解决了更改,因为我无法输出其他元素的唯一未决问题除了和。当然,如果您能帮助指出此处需要修改的内容,我们将不胜感激。@RoyTan,一般来说,回答后不要试图更改您的要求。取而代之的是,提出一个包含必要细节的新问题。对于链接到的示例,请检查中的更改是否符合您的要求。如果没有,请提出一个新问题,详细说明可能的输入结构以及哪些元素需要复制,哪些元素不需要复制。感谢Martin,他在下次发布新问题时指出。更新的更改解决了问题,所以这里一切都很好。
<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>