Following big problem:
<root>
<div>
<programm></programm>
<systemes><p></p></systemes>
<systemes><table>.1.</table></systemes>
<systemes><table>.2.</table></systemes>
<systemes><p></p></systemes>
<requirements></requirements>
</div>
<div>
<programm></programm>
<systemes><table>.1.</table></systemes>
<systemes><p></p></systemes>
<requirements></requirements>
</div>
<div>
<programm></programm>
<systemes><table>.1.</table></systemes>
<systemes><table>.2.</table></systemes>
<systemes><p></p></systemes>
<requirements></requirements>
</div>
</root>
I need the output to be this:
<root>
<div>
<programm></programm>
<systemes><p></p><table>.1.</table><table>.2.</table><p></p></systemes>
<requirements></requirements>
</div>
<div>
<programm></programm>
<systemes><table>.1.</table><p></p></systemes>
<requirements></requirements>
</div>
<div>
<programm></programm>
<systemes><table>.1.</table><table>.2.</table><p></p></systemes>
<requirements></requirements>
</div>
</root>
I hope someone can help me with this problem. I know the Muenchian Method but dont get it to work properly. Thank you very much!
This is what I tried so far:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="systemsKey" match="//systemes" use="name()"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="systemes[generate-id()=generate-id(key('systemesKey', name())[1])]">
<xsl:copy>
<xsl:apply-templates select="#*|key('systemesKey', name())/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="systemes[not(generate-id()=generate-id(key('systemesKey', name())[1]))]"/>
</xsl:stylesheet>
This produces exactly the output you described (except for the order of childs inside systemes elements).
<?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="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="requirements|programm|p">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:element name="systemes">
<xsl:for-each select="systemes">
<xsl:apply-templates/>
</xsl:for-each>
</xsl:element>
<xsl:apply-templates select="requirements|programm"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You do not need to use grouping at all, Muenchian or not. I would not advise you use something as complex as keys if it is not necessary for the goal you want to achieve.
EDIT: I have used XSLT 2.0 but there is nothing in it which cannot be done in 1.0.
Related
I am XSLT beginner, learning by example and by working on projects. Currently, I am working on creating grouped, nested structure from flat.
Consider this sample xml input:
<root>
<a>First text</a>
<b>Text</b>
<c>More text in c tag</c>
<d>There is even d tag</d>
<a>Another "a" test.</a>
<b>ěščřžýáíéúů</b>
<b>More b tags</b>
<c>One followed by c tag</c>
<a>Last a tag</a>
<b>This time only with b tag, but this goes on and on</b>
</root>
And this XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" method="xml" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" encoding="utf-8"/>
<xsl:key name="groupA" match="b|c|d" use="generate-id(preceding-sibling::a[1])" />
<xsl:key name="groupB" match="c|d" use="generate-id(preceding-sibling::b[1])"/>
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<wrapperTest>
<xsl:apply-templates/>
</wrapperTest>
</xsl:template>
<xsl:template match="root">
<xsl:apply-templates select="#*|a"/>
<xsl:apply-templates select="#*|b"/>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<xsl:apply-templates select="key('groupA', generate-id())" />
</xsl:copy>
</xsl:template>
<xsl:template match="b">
<xsl:copy>
<xsl:apply-templates select="key('groupB', generate-id())" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The expected output is:
<wrapperTest>
<a>First text
<b>Text
<c>More text in c tag</c>
<d>There is even d tag</d>
</b>
</a>
<a>Another "a" test.
<b>ěščřžýáíéúů</b>
<b>More b tags
<c>One followed by c tag</c>
</b>
</a>
<a>Last a tag
<b>This time only with b tag, but this goes on and on</b>
</a>
</wrapperTest>
In the transformation I created are excessive copies created and I have no idea why. I guess that the isuue I am hiting upon is basic in its nature, but I cant figure it out.
The only limit for solution is, that preferably it should be in XSLT 1.0 (since the project is incorporated in python script with lxml). In the edge case, when this couldnt be achived with XSLT 1.0, I can accomodate for recent saxon version which removes any limitations ...
I have already looked at answers here, here and others, but most of them use either XSLT 2.0 or are very complicated for a beginner to knive through.
Final note: Ideally, proposed solution should be extensible in it nature, because the final form of my project should be also grouped by tag <c>, like so:
<wrapperTest>
<a>First text
<b>Text
<c>More text in c tag
<d>There is even d tag</d>
</c>
</b>
</a>
<a>Another "a" test.
<b>ěščřžýáíéúů</b>
<b>More b tags
<c>One followed by c tag</c>
</b>
</a>
<a>Last a tag
<b>This time only with b tag, but this goes on and on</b>
</a>
</wrapperTest>
Which I will happily do as learning excersize.
How about:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="b" match="b" use="generate-id(preceding-sibling::a[1])" />
<xsl:key name="cd" match="c|d" use="generate-id(preceding-sibling::b[1])"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root">
<wrapperTest>
<xsl:apply-templates select="a"/>
</wrapperTest>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="key('b', generate-id())" />
</xsl:copy>
</xsl:template>
<xsl:template match="b">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="key('cd', generate-id())" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The recursive XSLT 2/3 for-each-group group-starting-with for all levels comes down to
<xsl:function name="mf:wrap" as="node()*">
<xsl:param name="input" as="node()*"/>
<xsl:for-each-group select="$input" group-starting-with="node()[node-name() = node-name($input[1])]">
<xsl:copy>
<xsl:sequence select="node(), mf:wrap(tail(current-group()))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="root">
<xsl:copy>
<xsl:sequence select="mf:wrap(*)"/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/gVhEaj8
I have an xml with subelements and need to change one of the subelement to attribute using XSLT 1.0
<TransportationRequest>
<actionCode>01</actionCode>
<ContractConditionCode>DC</ContractConditionCode>
<ShippingTypeCode>17</ShippingTypeCode>
<MovementTypeCode>3</MovementTypeCode>
<DangerousGoodsIndicator>false</DangerousGoodsIndicator>
<DefaultCurrencyCode>SAR</DefaultCurrencyCode>
The Expected xml is as below using the XSLT code:
<TransportationRequest actionCode="01">
<ContractConditionCode>DC</ContractConditionCode>
<ShippingTypeCode>17</ShippingTypeCode>
<MovementTypeCode>3</MovementTypeCode>
<DangerousGoodsIndicator>false</DangerousGoodsIndicator>
<DefaultCurrencyCode>SAR</DefaultCurrencyCode>
First, close the root tag on your xml:
<TransportationRequest>
<actionCode>01</actionCode>
<ContractConditionCode>DC</ContractConditionCode>
<ShippingTypeCode>17</ShippingTypeCode>
<MovementTypeCode>3</MovementTypeCode>
<DangerousGoodsIndicator>false</DangerousGoodsIndicator>
<DefaultCurrencyCode>SAR</DefaultCurrencyCode>
</TransportationRequest>
then this xsl will do what you asked for:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" />
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<!-- Copy every node as is -->
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TransportationRequest">
<!-- transform the TransportationRequest node in a special way -->
<xsl:element name="TransportationRequest">
<xsl:attribute name="actionCode"><xsl:value-of select="actionCode" /></xsl:attribute>
<!-- don't transform the actionCode node (is in the attribute) -->
<xsl:apply-templates select="#*|node()[name()!='actionCode']"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
You could to it like this :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="TransportationRequest">
<xsl:copy>
<xsl:attribute name="actionCode">
<xsl:value-of select="actionCode"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="actionCode"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See it working here : https://xsltfiddle.liberty-development.net/naZYrpW/1
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<web-inf metadata-complete="true">
<A>
<A1>DGDDG</A1>
<A1>TYTY</A1>
</A>
</web-inf>
When i am applying my transforms then the O/P XML is just dumping the <web-inf> tag without the metadata-complete="true" i.e as below
<?xml version="1.0" encoding="UTF-8"?>
<web-inf>
<A>
<A1>DGDDG</A1>
<A1>TYTY</A1>
</A>
</web-inf>
My XSLT Transform file has below in the beginning.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="web-inf[not(A/A1='hello')]">
<xsl:copy>
<xsl:call-template name="XXX"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Not sure what going wrong here.
Any suggestions?
<xsl:copy> copies only the current node, but not any attributes or child nodes. You are already catering for the child nodes with <xsl:apply-templates /> (which is equivalent to <xsl:apply-templates select="node()" />), but you also need to handle selecting attributes separately.
<xsl:template match="web-inf[not(A/A1='hello')]">
<xsl:copy>
<xsl:apply-templates select="#*" />
<xsl:call-template name="XXX"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
I am trying to use a key to group <p> elements based on whether they have a specific processing-instruction as a first preceding sibling, but I am having no luck.
For the following example input, I would like each <p> that has a first preceding-sibling processing-instruction that contains “key” to be grouped with its sibling <p> elements that meet the same criteria. Example input:
<root>
<p>not in key</p>
<?samplePI key?>
<p>start of key; </p>
<?samplePI key?>
<p>in key 1; </p>
<?samplePI key?>
<p>in key 2; </p>
<p>Not in key</p>
<?samplePI key?>
<p>start of new key; </p>
<?samplePI key?>
<p>in new key 3;</p>
</root>
Example output:
<root>
<p>not in key</p>
<p>start of key; in key 1; in key 2;</p>
<p>Not in key</p>
<p>start of new key; in new key 3;</p>
</root>
An example of what I've got:
<xsl:template match="root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="p">
<xsl:choose>
<xsl:when test="preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]][preceding-sibling::p[1][(preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]])]]">
</xsl:when>
<xsl:when test="preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]][preceding-sibling::p[1][not(preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]])]]">
<p><xsl:value-of select="text()"/>
<xsl:apply-templates select="key('nodes', generate-id())" mode="groupedParas"/>
</p>
</xsl:when>
<xsl:otherwise>
<p><xsl:apply-templates/></p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="p" mode="groupedParas">
<xsl:apply-templates/>
</xsl:template>
<xsl:key name="nodes" match="node()[(self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]])]" use="generate-id((preceding-sibling::p)[last()])"/>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
Note that I need the help with getting the correct key syntax, as opposed to generating the desired structure. I need to use XSLT 1.0 for this. Any help appreciated.
With XSLT 2.0 it looks manageable
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<p>
<xsl:apply-templates select="current-group()/node()"/>
</p>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
With XSLT 1.0 my usual approach is sibling recursion but it needs nastily long and convoluted match patterns:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="processing-instruction()[contains(., 'key')]"/>
<xsl:template match="p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and preceding-sibling::node()[2][not(self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]])]]">
<p>
<xsl:apply-templates select="." mode="collect"/>
</p>
</xsl:template>
<xsl:template match="p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and preceding-sibling::node()[2][self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]]]]"/>
<xsl:template match="p" mode="collect">
<xsl:apply-templates/>
<xsl:apply-templates select="following-sibling::node()[2][self::p and preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]]" mode="collect"/>
</xsl:template>
</xsl:stylesheet>
And finally, as you seem to want to use a key, a variation of the sibling recursion shown above which uses a key to identity a group of p elements, is as follows:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key name="collect"
match="p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and preceding-sibling::node()[2][self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]]]]"
use="generate-id(preceding-sibling::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and not(preceding-sibling::node()[2][self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]]])][1])"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="processing-instruction()[contains(., 'key')]"/>
<xsl:template match="p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and preceding-sibling::node()[2][not(self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]])]]">
<p>
<xsl:apply-templates select="./node() | key('collect', generate-id())/node()"/>
</p>
</xsl:template>
<xsl:template match="p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]
and preceding-sibling::node()[2][self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]]]]"/>
</xsl:stylesheet>
I have an XML document, and I want to change the values for one of the attributes.
First I copied everything from input to output using:
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
And now I want to change the value of the attribute "type" in any element named "property".
This problem has a classical solution: Using and overriding the identity template is one of the most fundamental and powerful XSLT design patterns:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pNewType" select="'myNewType'"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="property/#type">
<xsl:attribute name="type">
<xsl:value-of select="$pNewType"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
When applied on this XML document:
<t>
<property>value1</property>
<property type="old">value2</property>
</t>
the wanted result is produced:
<t>
<property>value1</property>
<property type="myNewType">value2</property>
</t>
Tested on a simple example, works fine:
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#type[parent::property]">
<xsl:attribute name="type">
<xsl:value-of select="'your value here'"/>
</xsl:attribute>
</xsl:template>
Edited to include Tomalak's suggestion.
The top two answers will not work if there is a xmlns definition in the root element:
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<property type="old"/>
</html>
All of the solutions will not work for the above xml.
The possible solution is like:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()[local-name()='property']/#*[local-name()='type']">
<xsl:attribute name="{name()}" namespace="{namespace-uri()}">
some new value here
</xsl:attribute>
</xsl:template>
<xsl:template match="#*|node()|comment()|processing-instruction()|text()">
<xsl:copy>
<xsl:apply-templates select="#*|node()|comment()|processing-instruction()|text()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You need a template that will match your target attribute, and nothing else.
<xsl:template match='XPath/#myAttr'>
<xsl:attribute name='myAttr'>This is the value</xsl:attribute>
</xsl:template>
This is in addition to the "copy all" you already have (and is actually always present by default in XSLT). Having a more specific match it will be used in preference.
I had a similar case where I wanted to delete one attribute from a simple node, and couldn't figure out what axis would let me read the attribute name. In the end, all I had to do was use
#*[name(.)!='AttributeNameToDelete']
I also came across same issue and i solved it as follows:
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!-- copy property element while only changing its type attribute -->
<xsl:template match="property">
<xsl:copy>
<xsl:attribute name="type">
<xsl:value-of select="'your value here'"/>
</xsl:attribute>
<xsl:apply-templates select="#*[not(local-name()='type')]|node()"/>
</xsl:copy>
</xsl:template>
For the following XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<property type="foo"/>
<node id="1"/>
<property type="bar">
<sub-property/>
</property>
</root>
I was able to get it to work with the following XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//property">
<xsl:copy>
<xsl:attribute name="type">
<xsl:value-of select="#type"/>
<xsl:text>-added</xsl:text>
</xsl:attribute>
<xsl:copy-of select="child::*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If your source XML document has its own namespace, you need to declare the namespace in your stylesheet, assign it a prefix, and use that prefix when referring to the elements of the source XML - for example:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- exception-->
<xsl:template match="xhtml:property/#type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Or, if you prefer:
...
<!-- exception-->
<xsl:template match="#type[parent::xhtml:property]">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
...
ADDENDUM:
In the highly unlikely case where the XML namespace is not known beforehand, you could do:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- exception -->
<xsl:template match="*[local-name()='property']/#type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
Of course, it's very difficult to imagine a scenario where you would know in advance that the source XML document contains an element named "property", with an attribute named "type" that needs replacing - but still not know the namespace of the document. I have added this mainly to show how your own solution could be streamlined.