XSLT:复制除属性包含值的所有XML

Jef*_*pia 3 xml xslt xsd

目标

我想复制所有XML,除非属性值包含特定字符,在本例中..如果.存在,请删除具有该属性及其所有子项的元素.我对xslt很新,并做了一些阅读,但我似乎无法找到一种方法来抓住父母及其所有孩子.

当前的XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:template match="@* | node()">

        <xsl:copy>

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

        </xsl:copy>

</xsl:template>

<xsl:template match="descendant-or-self::root/*/@name[contains(., '.')]" />
Run Code Online (Sandbox Code Playgroud)

示例XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <complexType name="tableData2File">
        <complexContent>
            <extension base="taskElement">
                <sequence>
                    <element name="source" type="tableData2File.source" />
                    <element name="parser" type="parser" />
                    <element name="target" type="node.uri" />
                </sequence>
                <attribute name="addNewColumns" type="minlength" use="optional" />                              
            </extension>
        </complexContent>
    </complexType>

    <!-- 
    match idViolationsCount.test,
    then remove all its content
     -->
    <complexType name="idViolationsCount.test">
        <complexContent>
            <extension base="tableTask">
                <sequence>
                    <element name="index" type="columnsNoAs" minOccurs="1" />
                    <element name="condition" type="stringWithRef" minOccurs="0" />
                    <element name="allowExpressions" type="boolWithRef" minOccurs="0" />
                </sequence>
                <attribute name="mode" type="mergeMode" use="required" />
            </extension>
        </complexContent>
    </complexType>

</root>
Run Code Online (Sandbox Code Playgroud)

期望的输出XML

<root>
    <complexType name="tableData2File">
        <complexContent>
            <extension base="taskElement">
                <sequence>
                    <element name="source" type="tableData2File.source" />
                    <element name="parser" type="parser" />
                    <element name="target" type="node.uri" />
                </sequence>
                <attribute name="addNewColumns" type="minlength" use="optional" />                              
            </extension>
        </complexContent>
    </complexType>

    <!-- no idViolationsCount.test! --> 
</root>
Run Code Online (Sandbox Code Playgroud)

Ian*_*rts 6

这看起来像是正确的方法(一个身份模板,为你要删除的东西而被覆盖),但你不能descendant-or-self::在匹配模式中使用.但是,你不需要,只是

<xsl:template match="root/*[contains(@name, '.')]" />
Run Code Online (Sandbox Code Playgroud)

应该做的工作.请注意,您的原始匹配模式root/*/@name[contains(., '.')]将匹配name属性节点,而不是托管它的元素,因此您最终将删除该属性,但保持元素不变.

你不需要对被删除元素的子元素做任何特殊操作 - 这个空模板将删除整个元素,包括其内容,如果你想删除这个元素但保留它的子元素,那么你需要一个不同的模板

<xsl:template match="root/*[contains(@name, '.')]">
  <!-- don't output anything now, but keep processing children -->
  <xsl:apply-templates />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)