我需要创建一个XSLT来遵循两个规则(按优先级顺序):


应该复制以/xs:schema/node()。此/xs:schema/node()/@name应包括所有后代和属性。
应该创建一个仅包含后代的/xs:schema/node(),该后代的任何属性均以“ prefix_”开头


我所使用的文件采用这种格式

<?xml version="1.0" encoding="UTF-8"?>
<!--
    this is
    a really long
    comment
    that spans
    multiple lines
-->
<!-- <!a comment > another comment -->
<!-- <!a comment > another comment -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified"
    attributeFormDefault="unqualified">

    <!-- a comment -->
    <xs:node name="ABC">
        <xs:node>
            <xs:element/>
            <xs:element attr="asdf"/>
        </xs:node>
    </xs:node>
    <!-- <!a comment > another comment -->
    <node name="DEF">
        <element/>
        <element attr="asdf" bttr="zxcv"/>
    </node>
    <!-- <!a comment > another comment -->
    <node name="prefix_a">
        <element/>
        <element attr="asdf"/>
        <element attr="prefix_attr"/>
        <element battr="prefix_battr"/>
    </node>

    <node name="prefix_b">
        <node>
            <element/>
            <element battr="prefix_bttr"/>
            <element hattr="prefix_cattr"/>
        </node>
    </node>

    <node name="c">
        <node>
            <node>
                <node>
                    <node>
                        <element attr="qwerty"/>
                        <element attr="zxvc"/>
                        <element attr="asdf"/>
                        <element battr="prefix_bttr"/>
                        <element flattr="prefix_hattr"/>
                    </node>
                </node>
            </node>
        </node>
    </node>

    <node name="d">
        <element/>
        <element attr="asdf"/>
        <element shattr="prefix_shattr"/>
        <element cattr="prefix_battr"/>
    </node>
    <!-- <!a comment > another comment -->
    <node name="g">
        <element attr="asdf" bttr="zxcv"/>
        <element/>
    </node>

</xs:schema>


XSLT应该返回;

<xml>
<xs:schema>

  <node name="prefix_a">
    <element />
    <element attr="asdf" />
    <element attr="prefix_attr" />
    <element battr="prefix_battr" />
  </node>

  <node name="prefix_b">
    <node>
      <element />
      <element battr="prefix_bttr" />
      <element hattr="prefix_cattr" />
    </node>
  </node>

  <node name="c">
    <node>
      <node>
        <node>
          <node>
            <element battr="prefix_bttr" />
            <element flattr="prefix_hattr" />
          </node>
        </node>
      </node>
    </node>
  </node>

  <node name="d">
    <element shattr="prefix_shattr" />
    <element cattr="prefix_battr" />
  </node>

</xs:schema>


我在下面使用以下XSLT;

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsl:namespace-alias stylesheet-prefix="xs" result-prefix="xsd"/>

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates select="xsd:schema"/>
    </xsl:template>

    <xsl:template match="xsd:schema">
        <xs:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified"
            attributeFormDefault="unqualified" version="1.0">
            <xsl:apply-templates select="node()[starts-with(@name, 'prefix_')]"/>
            <xsl:apply-templates select="node()[descendant::node()/@*[starts-with(., 'prefix_')]]"/>
        </xs:schema>
    </xsl:template>

    <xsl:template match="xsd:schema/node()[starts-with(@name, 'prefix_')]">
        <xsl:copy-of select="current()"/>
    </xsl:template>

    <xsl:template match="xsd:schema/node()[descendant::node()/@*[starts-with(., 'prefix_')]]">
        <xsl:copy-of select="current()"/>
    </xsl:template>


</xsl:stylesheet>

最佳答案

我已经修复了@Dimitre注意到的愚蠢错误。

现在,进行以下转换:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="xs:schema/*[
        not(starts-with(@name,'prefix_'))
            and
            not(.//*/@*[starts-with(.,'prefix_')])]"/>

    <xsl:template match="*[
        not(*)
            and
        not(@*[starts-with(.,'prefix_')])
            and
        not(ancestor::*[starts-with(@name,'prefix_')])
        ]"/>

</xsl:stylesheet>


给定此输入(稍作修改以涵盖更复杂的情况):

<xml>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

        <!-- a comment -->

        <node name="prefix_a">
            <element />
            <element attr="asdf" />
            <element x="y" attr="prefix_attr" />
            <element battr="prefix_battr" y="x"/>
        </node>

        <node name="prefix_b">
            <node>
                <element />
                <element battr="prefix_bttr" />
                <element hattr="prefix_cattr" />
            </node>
        </node>

        <node name="c">
            <node>
                <node>
                    <node>
                        <node>
                            <element attr="qwerty" />
                            <element attr="zxvc" />
                            <element attr="asdf" />
                            <element battr="prefix_bttr" x="y"/>
                            <element flattr="prefix_hattr" y="x"/>
                        </node>
                    </node>
                </node>
            </node>
        </node>

        <node name="d">
            <element />
            <element attr="asdf" />
            <element shattr="prefix_shattr" />
            <element cattr="prefix_battr" />
        </node>

        <node name="e">
            <element />
            <element attr="asdf" />
        </node>

    </xs:schema>
</xml>


产生:

<xml>
   <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <node name="prefix_a">
         <element/>
         <element attr="asdf"/>
         <element x="y" attr="prefix_attr"/>
         <element battr="prefix_battr" y="x"/>
      </node>
      <node name="prefix_b">
         <node>
            <element/>
            <element battr="prefix_bttr"/>
            <element hattr="prefix_cattr"/>
         </node>
      </node>
      <node name="c">
         <node>
            <node>
               <node>
                  <node>
                     <element battr="prefix_bttr" x="y"/>
                     <element flattr="prefix_hattr" y="x"/>
                  </node>
               </node>
            </node>
         </node>
      </node>
      <node name="d">
         <element shattr="prefix_shattr"/>
         <element cattr="prefix_battr"/>
      </node>
   </xs:schema>
</xml>

关于xslt - XSLT使用字符串匹配修改身份规则,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7433237/

10-15 02:57