简体   繁体   中英

XSLT to remove some attributes

I have the following XML which can appear in either form in my XML Document:

<Message xsi:schemaLocation="http://www.location.com StructureFile.xsd" xmlns=http://www.thenamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

or

<Message xmlns="http://www.thenamespace.com">

and I need the output to be:

<Message xmlns="http://www.theNEWnamespace.com">

I currently have this template to handle the shorter version of the two xml possibilities:

<xsl:template match="*">
  <xsl:element name="{name()}" namespace="http://www.theNEWnamespace.com">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

However this does not remove the SchemeLocation or xmlns:xsi parts of the xml if they are in existance.

How would I go about adapting the above to handle both possibilities.

Cheers,

Edit: XML structure:

<?xml version="1.0" encoding="utf-8"?>
<Message xsi:schemaLocation="http://www.location.com StructureFile.xsd" xmlns="http://www.thenamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header>
    <Info></Info>
  </Header>
</Message>

Here is a complete transformation producing the wanted result :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://www.thenamespace.com">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="x:Message">
  <xsl:element name="{name()}" namespace="http://www.theNEWnamespace.com">
    <xsl:copy-of select="@*[not(name() = 'xsi:SchemaLocation')]"/>
    <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the following XML document (none provided!):

<t>
  <Message
  xsi:SchemaLocation="http://www.location.com StructureFile.xsd"
  xmlns="http://www.thenamespace.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</t>

the wanted, correct result is produced:

<Message xmlns="http://www.theNEWnamespace.com"/>

First of all, in the XSLT/XPath data model only the xsi:schemaLocation is an attribute. If you don't want to copy that attribute or any attributes at all, well, then don't do <xsl:copy-of select="@*"/> because there you explicitly copy all attributes. Or if you want to selectively specify which attributes not to copy then instead of the <xsl:copy-of select="@*"/> put in <xsl:apply-templates select="@*"/> , then write one template for copying attributes and then templates for those attributes you don't want to copy eg

<xsl:template match="@*">
  <xsl:copy/>
</xsl:template>

<xsl:template match="@xsi:schemaLocation"/>

As for xmlns:xsi , that is a namespace declaration which in the XSLT/XPath data model is not an attribute. And if all you do for element nodes is the template you have shown then I don't see how that namespace should be copied through to the output.

If you however define namespaces in the stylesheet too then you need exclude-result-prefixes="xsi" on the xsl:stylesheet element.

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