XML to XML with XSLT- Add, Remove, Modify Elements

2019-08-17 11:14发布

问题:

I want to change from one XML (XHTML) file to another using XSLT. In the new XML file I have to remove/add/modify some elements. So for that I created one identity.xsl file, which copies the entire source file and then I created a new XSLT which includes identity.xsl and then in that new XSLT I'm trying to do the modifications. I'm able to eliminate a few attributes, which are not required, by passing a template match which does nothing but I'm unable to add the new attributes in the existing tags and also unable to add the new elements at the specific location (with closing tags at particular location).

My Original file:

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
</head>

<body>
  <div id="o">
    <div id="nd">
      <p>1</p>
    </div>

    <div class="TF id="id12">
      <element1 name="abc" src="abc.jpg"></script>
      <input type="radio" id="1" event="xyz">
      <div class="q">
        <br/>
        <div id="ta3" class="block">
          <span style="a">ABC</span>
        </div>
        <br/>T <input/> F <input/>
        <div id="sf">
          <div id="ta3">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</body>
</html>

Required file:

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
</head>

<!--HAVE TO AD THESE TWO ELEMENTS-->
<element add="xyz" id="23">
<element add="xyz" id="24">

<!--ADD ATTRIBUTES IN BODY TAG-->
<body onLoad="ada" bgcolor="pink">

  <div id="o">
    <div id="nd">
      <p>1</p>
    </div>

    <div class="TF id="id12">

      <!--HAVE TO UPATE THE VALUE OF SRC ATTRIBUTE -->
      <element1 name="abc" src="xyz.jpg"></script>

      <!--ADD THIS FORM ELEMENT WITH ATTRIBUTE-->
      <form name="form">
        <input type="radio" id="1" event="xyz">
        <div class="q">
          <br/>
          <div id="ta3" class="block">
            <span style="a">ABC</span>
          </div>

          <br/>T 
          <!--ADD TABLE/TR/TD TAG-->
          <table>
            <tr>
              <td>
                <input/>
              </td>
            </tr>
            <tr>
              </td>
              F <input/>
              </td>
            </tr>
          </table>

          <div id="sf">
            <div id="ta3">
            </div>
          </div>
        </div>

        <!--ADD INPUT TAG-->
        <input type="submit" value="Done"/>

      </div>
    </div>

    <!--CLOSE FORM TAG-->
  </form>
</div>
</body>
</html>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- Import the identity transformation. -->
  <xsl:import href="identity.xsl"/>

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

  <xsl:template match="body">
    <body onLoad="ada" bgcolor="pink"></body>
  </xsl:template>

  <!--REMOVES THE MATCHING ATTRIBUTE and DOES THE JOB-->
  <xsl:template match="@attr"> </xsl:template>

  <xsl:template match="input">
    <xsl:element name="input">
      <xsl:attribute name="type">submit</xsl:attribute>
      <xsl:attribute name="value">Done</xsl:attribute>
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

回答1:

Your input document was so full of formation errors, I've had to take the risk of guessing your intentions. Please see the transform solution below. I deliberately did not include the insertion of the table elements around your comment "ADD TABLE/TR/TD TAG", as this section seemed so nutty that any solution that I provided for you here would likely be a wrong interpretation of your required rules of transformation.

This XSLT 1.0 style-sheet ...

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

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

<xsl:template match="xhtml:body">
  <element add="xyz" id="23" />
  <element add="xyz" id="24" />
 <body onLoad="ada" bgcolor="pink">
  <xsl:apply-templates select="@*|node()"/>
  </body>
</xsl:template>

<xsl:template match="xhtml:element1[@name='abc']/@src">
  <xsl:attribute name="src">xyz.jpg</xsl:attribute>  
</xsl:template>

<xsl:template match="xhtml:input[@id='1']">
  <form name="form">
   <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
   <xsl:apply-templates select="following-sibling::xhtml:div[1]" mode="inside-form"/> 
  </form>
</xsl:template>

<xsl:template match="xhtml:div[ preceding-sibling::xhtml:*[1]
   /self::xhtml:input[@id='1']]"/>

<xsl:template match="xhtml:div" mode="inside-form">
 <xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
 <input type="submit" value="Done"/> 
</xsl:template>

</xsl:stylesheet>

... will take this input document ...

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
</head>
<body>
 <div id="o">
  <div id="nd">
   <p>1</p>
  </div>
  <div class="TF" id="id12">
   <element1 name="abc" src="abc.jpg"/>
   <input type="radio" id="1" event="xyz"/>
   <div class="q">
    <br/>
    <div id="ta3" class="block">
     <span style="a">ABC</span>
    </div>
    <br/>T <input/> F <input/>
    <div id="sf">
     <div id="ta3">
     </div>
    </div>
   </div>
  </div>
 </div>
</body>
</html>

...and yield this output document ...

<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
  </head>
  <element add="xyz" id="23" />
  <element add="xyz" id="24" />
  <body onLoad="ada" bgcolor="pink">
    <div id="o">
      <div id="nd">
        <p>1</p>
      </div>
      <div class="TF" id="id12">
        <element1 name="abc" src="xyz.jpg" />
        <form name="form">
          <input type="radio" id="1" event="xyz" />
          <div class="q">
            <br />
            <div id="ta3" class="block">
              <span style="a">ABC</span>
            </div>
            <br />T <input /> F <input /><div id="sf"><div id="ta3" /></div></div>
          <input type="submit" value="Done" />
        </form>
      </div>
    </div>
  </body>
</html>


回答2:

Personally, I can't stand XSL-T. It's too hard to read.

My preference is to create a Velocity template of the XML I want to produce and use Velocity to map from the old XML to the new. It's easier to visualize and works just as well.



标签: xml xslt xhtml