How to add element to XML via XSL

2019-09-20 06:26发布

I have created a simple XSL file which performs transformation on XML file. Now the transformation returns True or False (depending on the result of the test) if passed = true, fail = false. Now i want to add extra tag into my XML with this values I have seen this post and tried to adapt this into my problem however it didn't quite work.

My xml file initially looks like this

<?xml version="1.0" encoding="iso-8859-1"?>
<message>
  <unique-id>unique-id</unique-id>
  <payload>
      <Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://mappings.f4f.com/F4FXML/Schemas/v5/financial.xsd">
      <EnvelopeHeader>
          <SchemaVersion>5.1</SchemaVersion>
          <EnvelopeCreated>20140108</EnvelopeCreated>
          <EnvelopeTrackingID>1746978</EnvelopeTrackingID>
          <EnvelopeRevisionNumber>1</EnvelopeRevisionNumber>
          <SourcePartnerID>UK0000001088</SourcePartnerID>
          <SourceDivisionID>UK0000001088</SourceDivisionID>
          <DestinationPartnerID>ang</DestinationPartnerID>
          <DestinationDivisionID>9725652</DestinationDivisionID>
          <TestIndicator>True</TestIndicator>
      </EnvelopeHeader>
       <!--...... stuff totally irrelevant below-->
      </Envelope>
  </payload>
    <metadata>
        <metadata-element>
            <key>messageuniqueid</key>  
            <value>unique-id</value>
        </metadata-element>
        <metadata-element>
            <key>PostCode</key>
            <value>NR9 5BZ</value>
        </metadata-element>
    </metadata>
</message>

Then I run some transformation file that tests if a given value of element is as expected or not. My output message should look like this:

<message>
  <unique-id>unique-id</unique-id>
  <payload>Some gibberish here</payload>
    <metadata>
        <metadata-element>
            <key>messageuniqueid</key>  
            <value>unique-id</value>
        </metadata-element>
        <metadata-element>
            <key>PostCode</key>
            <value>NR9 5BZ</value>
        </metadata-element>
        <metadata-element>
            <key>TestResult</key>
            <value>True / False</value>
        </metadata-element>
    </metadata>
</message> 

The XML file that I currently have is this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<axsl:stylesheet xmlns:axsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:exsl="http://exslt.org/common" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="2.0">
   <axsl:output method="text"/>
   <axsl:template match="*|@*" mode="schematron-get-full-path">
      <axsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
      <axsl:text>/</axsl:text>
      <axsl:if test="count(. | ../@*) = count(../@*)">@</axsl:if>
      <axsl:value-of select="name()"/>
      <axsl:text>[</axsl:text>
      <axsl:value-of select="1+count(preceding-sibling::*[name()=name(current())])"/>
      <axsl:text>]</axsl:text>
   </axsl:template>
   <axsl:template match="/">
      <axsl:apply-templates select="/" mode="M0"/>
   </axsl:template>
   <axsl:template match="Envelope/EnvelopeHeader" priority="101" mode="M0">
      <axsl:choose>
         <axsl:when test="EnvelopeTrackingID = 1746978">
            <axsl:copy-of select="true()"/>
         </axsl:when>
         <axsl:otherwise>
            <axsl:copy-of select="false()"/>
         </axsl:otherwise>
      </axsl:choose>
      <axsl:apply-templates mode="M0"/>
   </axsl:template>
   <axsl:template match="text()" priority="-1" mode="M0"/>
   <axsl:template match="text()" priority="-1"/>
</axsl:stylesheet>

As you can see I do set true / false depending on the test result but now how do I add this to the metadata-element tags ? as key value ?

Thanks

1条回答
Root(大扎)
2楼-- · 2019-09-20 07:06

I decided to write a stylesheet from scratch, since your XSLT is full of functionality that is irrelevant to your question and simply confusing. Your question is how to add a metadata-element to the output after testing for a value and that's what I illustrate here.

The following stylesheet performs an identity transform with one exception, namely adding a metadata-element element. (By the way, you might want to reconsider naming an element "element").

The value of the new metadata-element depends on the value of EnvelopeTrackingID.

Stylesheet

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

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="metadata">
  <xsl:copy>
     <xsl:apply-templates/>
     <metadata-element>
        <key>TestResult</key>
        <value>
           <xsl:choose>
              <xsl:when test="preceding-sibling::payload/Envelope/EnvelopeHeader/EnvelopeTrackingID = '1746978'">
                 <xsl:text>true</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                 <xsl:text>false</xsl:text>
              </xsl:otherwise>
           </xsl:choose>
        </value>
     </metadata-element>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Output

<?xml version="1.0" encoding="UTF-8"?>
<message>
 <unique-id>unique-id</unique-id>
 <payload>
  <Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="http://mappings.f4f.com/F4FXML/Schemas/v5/financial.xsd">
     <EnvelopeHeader>
        <SchemaVersion>5.1</SchemaVersion>
        <EnvelopeCreated>20140108</EnvelopeCreated>
        <EnvelopeTrackingID>1746978</EnvelopeTrackingID>
        <EnvelopeRevisionNumber>1</EnvelopeRevisionNumber>
        <SourcePartnerID>UK0000001088</SourcePartnerID>
        <SourceDivisionID>UK0000001088</SourceDivisionID>
        <DestinationPartnerID>ang</DestinationPartnerID>
        <DestinationDivisionID>9725652</DestinationDivisionID>
        <TestIndicator>True</TestIndicator>
     </EnvelopeHeader>
     <!--...... stuff totally irrelevant below-->
  </Envelope>
 </payload>
 <metadata>
    <metadata-element>
        <key>messageuniqueid</key>  
        <value>unique-id</value>
    </metadata-element>
    <metadata-element>
        <key>PostCode</key>
        <value>NR9 5BZ</value>
    </metadata-element>
  <metadata-element>
     <key>TestResult</key>
     <value>true</value>
  </metadata-element>
 </metadata>
</message>
查看更多
登录 后发表回答