通过xsl移动标签部件

时间:2017-08-02 15:21:28

标签: xml xslt xpath

是否有可能改变这样的东西

<tag name="a"/>
<something>
    <endtag name="a"/>
    <tag name="b"/>
</something>
<endtag name="b"/>

到这个

<something>
    <tag name="a"/>
    <endtag name="a"/>
    <tag name="b"/>
    <endtag name="b"/>
</something>

通过xsl转换?所以我知道<something>可能会或可能不会在相应的<tag><endtag>之间,这很糟糕,我必须移动它。

UPD: 更多信息。假设我们有一个输入xml,它有3种类型的标记:<tag><endtag><something>。我们的目标是以每种方式转换它,例如,<tag name="a"/>变为<a><endtag name="a"/>变为</a><something>只保留<something> 。因此,使用我提供的第一个XML,它将导致格式不正确的XML,正是这样:

<a>
<something>
    </a>
    <b>
</something>
</b>

因此,我需要做一些准备工作,并按照<something>的方式进行扩展,并在其中包含<tag><endtag>,而不仅仅是其中之一。

UPD 2: 1)我们有什么 2)需要什么

1 个答案:

答案 0 :(得分:0)

  

我只需要移动第一个前一个和后一个兄弟姐妹

考虑以下示例:

XML

<root>
    <tag name="a"/>
    <tag name="b"/>
    <something>
        <endtag name="c"/>
        <tag name="d"/>
    </something>
    <endtag name="e"/>
    <endtag name="f"/>
</root>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="something">
    <xsl:copy>
        <xsl:copy-of select="preceding-sibling::tag[1]"/>
        <xsl:apply-templates/>
        <xsl:copy-of select="following-sibling::endtag[1]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="tag[following-sibling::*[1][self::something]] | endtag[preceding-sibling::*[1][self::something]]"/>

</xsl:stylesheet>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <tag name="a"/>
  <something>
    <tag name="b"/>
    <endtag name="c"/>
    <tag name="d"/>
    <endtag name="e"/>
  </something>
  <endtag name="f"/>
</root>