XSLT查找所有相关元素

问题描述

我试图找出XSLT是否可用于转换以下XML(代码段,因为它包含更多元素),以便转换后的XML仅包含子元素中指定的内容元素。

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.
  <span>Lorem Ipsum has been the industry's standard dummy text ever since the
     1500s,when an unkNown printer took a galley of type and scrambled it to make a
     type specimen book.</span> It has survived not only five centuries,but also the leap into electronic typesetting,remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>

<?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" 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>

解决方法

也许像这样:

<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