如何删除标签?

How to remove a tag?

要更新的第一个 xml 文件“in.xml”:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11"/>
            <Chartr />
            <Chartu />
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn />
                </d>
                <m5 attr5="gd"/>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto />
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd />
        <m2 />
    </xItem>
</root>

从中获取数据以更新第一个文件的第二个 xml 文件“updates.xml”:

<updates attr="updates">
    <xItem key="1">
        <b>
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chartr>
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2"/>
                </Widget>
            </Chartu>
            <Itemz key="2">
                <d>
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52"/>
                        </Widget>
                    </Chartn>
                </d>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59"/>
                    </Widget>
                </Charto>
            </Itemt>
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59"/>
            </Widget>
        </Chartd>
    </xItem>
</updates>

XSLT1.0 转换文件,其中 ancestors 变量包含来自第二个“updates.xml”文件的 Widget 标记的第一个祖先。更进一步,在复制源文件时,我们从祖先变量中添加更新数据:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:variable name="filename" select="'updates.xml'" />
  
  <xsl:variable name="ancestors" select="document('updates.xml')//Widget/ancestor::*[1]" />
  
  <xsl:template match="@*|node()">
    <xsl:variable name="element" select="name()"/>
    
    <xsl:for-each select="$ancestors">
     <xsl:variable name="var" select="local-name()"/> 
      
     <xsl:if test="$element=$var">
        <xsl:copy-of select="(.)"/>
        <xsl:text>&#10;</xsl:text>
     </xsl:if>
     </xsl:for-each> 
          
     <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>  

  </xsl:template>

</xsl:stylesheet>

转换文件后:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11" />
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6" />
                </Widget>
            </Chartr>
<Chartr />
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2" />
                </Widget>
            </Chartu>
<Chartu />
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52" />
                        </Widget>
                    </Chartn>
<Chartn />
                </d>
                <m5 attr5="gd" />
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59" />
                    </Widget>
                </Charto>
<Charto />
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59" />
            </Widget>
        </Chartd>
<Chartd />
        <m2 />
    </xItem>
</root>

合并后如何去掉不需要的标签'Chartr'、'Chartu'、'Chartn'、'Charto'、'Chartd',使改造后有这样一个文件:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11"/>
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chartr>
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2"/>
                </Widget>
            </Chartu>
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52"/>
                        </Widget>
                    </Chartn>
                </d>
                <m5 attr5="gd"/>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59"/>
                    </Widget>
                </Charto>
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59"/>
            </Widget>
        </Chartd>
        <m2 />
    </xItem>
</root>

也许这样就足够了:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exslt="http://exslt.org/common"
  exclude-result-prefixes="exslt"
  version="1.0">
  
  <xsl:key name="replacement" match="*[Widget]" use="local-name()"/>
  
  <xsl:output method="xml"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="*[not(node())]">
    <xsl:variable name="this" select="."/>
    <xsl:variable name="replacement">
      <xsl:for-each select="$updates">
        <xsl:copy-of select="key('replacement', local-name($this))"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="exslt:node-set($replacement)/*">
        <xsl:copy-of select="$replacement"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:param name="updates" select="document('updates.xml')"/>

</xsl:stylesheet>