Reputation: 11
I am trying to perform a very simple change of an XML tag from one thing to another. I dont want any other things in the xml file to change. For technical reasons I have to use XSLT to perform this.
I have looked at this posting Changing One Tag Name in an XML File Using XSLT but the logic doesnt seem to work on it.
my input XML is this and all I want to be able to do is change the Sync open and close tags to Process open and close tags respectively.
<SyncCodeDefinition xmlns="xxx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.xxx.com/OAGIS/2 http://schema.xxx.com/2.6.5/OAGIS/BODs/Developer/mytest.xsd" releaseID="9.2">
<ApplicationArea>
<Sender>
<LogicalID schemeVersionID="12345">lid://xxx.yyy.zzz</LogicalID>
<ComponentID>test1</ComponentID>
</Sender>
<CreationDateTime>2012-09-11T17:07:04Z</CreationDateTime>
<BODID>xxxxx</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<TenantID>xxxx</TenantID>
<AccountingEntityID>ZZZ</AccountingEntityID>
<ActionCriteria>
<ActionExpression actionCode="Add" />
</ActionCriteria>
</Sync>
<CodeDefinition>
<DocumentID>
<ID accountingEntity="ZZZ" variationID="1">TEST001_PRODUCT</ID>
</DocumentID>
<DisplayID>TEST001_PRODUCT</DisplayID>
<Status>
<Code listID="CodeDefinitionStatus">Open</Code>
</Status>
<ListID>PRODUCT</ListID>
<CodeValue accountingEntity="ZZZ" languageID="en-GB">TEST001</CodeValue>
<Name languageID="en-GB">new test</Name>
<Description languageID="en-GB">new test</Description>
</CodeDefinition>
</DataArea>
</SyncCodeDefinition>
This is my XSLT but it seems to ignore the replace statement. please help :)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"Sync[count(.|((//Sync)[1])) = 1]">
<Process>
<xsl:apply-templates />
</Process>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 558
Reputation: 27996
The template match expression is not using the namespace for the <Sync>
element. You need to change it to:
<xsl:template match= "xxx:Sync[count(.|((//xxx:Sync)[1])) = 1]">
and add a namespace declaration to your <xsl:stylesheet>
element:
xmlns:xxx="xxx"
This is an XML FAQ. Your XML input document has a default namespace declaration on the outermost element:
xmlns="xxx"
This means that all of this element's descendants, including <Sync>
, are in the namespace whose URI is "xxx", unless otherwise specified.
Remember that namespace prefixes (or lack thereof) and declarations per se are ignored by the XML information model that XSLT and XPath use. They only care about what namespace (identified by its namespace URI) a node is in.
Also remember (as a corollary) that the namespace prefixes used in the XML input document are completely separate from any namespace prefixes declared in your stylesheet. This make sense, because you could be processing multiple input documents, each of which might use the same prefixes in different ways (and that even within the same XML document).
In XSLT 1.0, there is no way to specify what namespace to use as a default namespace (i.e. what namespace to use when there is no namespace prefix) in match patterns (or XPath expressions). So you have to declare a prefix for any namespace you want to use, and then use that prefix in your match patterns. As shown above.
Upvotes: 2