简体   繁体   中英

How do I move an element in XSLT if it exists

I've been tasked with tidying up some XML so despite a rather loose DTD, everything is declared in the same way. For example, in the elements below

<all>
<e>
    <hg>
        <hw>things</hw>
        <posg><pos value="abc" /></posg>
    </hg>
    <sg><se1 /></sg>
</e>
<e>
    <hg>
        <hw>stuff</hw>
        <posg><pos value="def" /></posg>
    </hg>
    <sg>
        <se1>
            <posg><pos value="ghi" /></posg>
        </se1>
    </sg>
</e>
</all>

the <posg> element should be a child of <se1> and not <hg> . Furthermore, if a <posg> element already exists in the <se1> element, then I should create a new <se1> element as the first child of <sg> and then move the <posg> element from <hg> to the new <se1> element.

In effect then, the two elements above should look like this after transformation

<all>   
    <e>
        <hg>
            <hw>things</hw>
        </hg>
        <sg>
            <se1>
                <posg><pos value="abc" /></posg>
            </se1>
        </sg>
    </e>
    <e>
        <hg>
            <hw>stuff</hw>
        </hg>
        <sg>
            <se1>
                <posg><pos value="def" /></posg>
            </se1>
            <se1>
                <posg><pos value="ghi" /></posg>
            </se1>

        </sg>
    </e>
</all>

I have been struggling with how to check whether the rogue <posg> element exists within <hg> and then take the appropriate action described above.

Use the following script:

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

  <xsl:template match="sg">
    <xsl:copy>
      <xsl:if test="../hg/posg">
        <se1><xsl:copy-of select="../hg/posg"/></se1>
      </xsl:if>
      <xsl:if test="se1/posg">
        <xsl:apply-templates select="@*|node()"/>
      </xsl:if>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="hg/posg"/>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM