xslt - How can I copy an XML structure into another one except some attributes or nodes -


with xml structure below:

<root foo1="bar1" foo2="bar2" foo3="bar3">     <foo1 foo1="bar1" />      <data>         <foo1>bar1</foo1>         <foo2>bar2</foo2>         <foo3>bar3</foo3>     </data> </root> 

i copy xml structure 1 exception on attributes and/or node() names , following result using xslt 1.0:

<root foo1="bar1" foo2="bar2">         <data>         <foo1>bar1</foo1>         <foo3>bar3</foo3>     </data> </root> 

my rules are:

1) copy every root attributes except foo3

2) copy every child nodes() unless ones named foo1 , foo2

my actual xsl stylesheet. managed root attributes restriction working :

<xsl:template match="root">     <root>         <xsl:for-each select="./@*">             <xsl:variable name="name" select="name()" />              <xsl:if test="name() != 'foo3'">                 <xsl:attribute name="{$name}"><xsl:value-of select="." /></xsl:attribute>             </xsl:if>         </xsl:for-each>       </root> </xsl:template> 

also, 1 harder question: if want matches attributes , nodes dynamically. specify server-side attributes , nodes() remove. it's generating string used in <xsl:if>. don't know if that's possible.

thank you.

i copy xml structure 1 exception [...]

my rules are:

1) copy every root attributes except foo3

2) copy every child nodes() unless ones named foo1 , foo2

update comments:

hi, work. except data/foo1 should copied

this stylesheet:

<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="root/@foo3|root/foo1|foo2"/> </xsl:stylesheet> 

output:

<root foo1="bar1" foo2="bar2">     <data>         <foo1>bar1</foo1>         <foo3>bar3</foo3>     </data> </root> 

note: overwriting identity rule empty templates

with node names in parameter, stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">     <xsl:param name="pstrip" select="'root/@foo3|root/foo1|foo2'"/>     <xsl:template match="node()|@*" name="identity">         <xsl:param name="pstrippaths" select="concat($pstrip,'|')"/>         <xsl:param name="pnodepath">             <xsl:call-template name="path"/>             <xsl:text>|</xsl:text>         </xsl:param>         <xsl:variable name="vstrippath"                       select="substring-before($pstrippaths,'|')"/>         <xsl:choose>             <xsl:when test="not($pstrippaths)">                 <xsl:copy>                     <xsl:apply-templates select="node()|@*"/>                 </xsl:copy>             </xsl:when>             <xsl:when test="contains($pnodepath,concat('/',$vstrippath,'|'))"/>             <xsl:otherwise>                 <xsl:call-template name="identity">                     <xsl:with-param name="pstrippaths"                                     select="substring-after($pstrippaths,'|')"/>                     <xsl:with-param name="pnodepath" select="$pnodepath"/>                 </xsl:call-template>             </xsl:otherwise>         </xsl:choose>     </xsl:template>     <xsl:template match="node()" name="path" mode="path">         <xsl:apply-templates select="parent::*" mode="path"/>         <xsl:value-of select="concat('/',                                      substring('@',                                                1 div (count(.|../@*)                                                       = count(../@*))),                                      name())"/>     </xsl:template> </xsl:stylesheet> 

output:

<root foo1="bar1" foo2="bar2">     <data>         <foo1>bar1</foo1>         <foo3>bar3</foo3>     </data> </root> 

note: in xml, element name refers schema, defining hierarchie position, yours not case.

edit: fun, xslt 2.0 solution:

<xsl:stylesheet version="2.0"      xmlns:xsl="http://www.w3.org/1999/xsl/transform"      xmlns:xs="http://www.w3.org/2001/xmlschema"      xmlns:local="http://localhost">     <xsl:param name="pstrip" select="'root/@foo3|root/foo1|foo2'"/>     <xsl:template match="node()|@*">         <xsl:copy>             <xsl:apply-templates select="node()|@*"/>         </xsl:copy>     </xsl:template>     <xsl:template match="*[local:match($pstrip,.)]|@*[local:match($pstrip,.)]"/>     <xsl:function name="local:match" as="xs:boolean">         <xsl:param name="pstrippaths" as="xs:string"/>         <xsl:param name="pnode" as="item()"/>         <xsl:variable name="vnodepath"                       select="string-join(($pnode                                             /ancestor::node()                                              /name(),                                            if ($pnode instance of attribute())                                            concat('@',name($pnode))                                            else name($pnode)),                                            '/')"/>         <xsl:sequence select="some $path in tokenize($pstrippaths,'\|')                                   satisfies ends-with($vnodepath,                                                       concat('/',$path))"/>     </xsl:function> </xsl:stylesheet> 

edit 2: stylesheet following same string pattern.


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -