


All
I have an XML document of the following form:
<RootNode>
<ChildNode>
<ChildA/>
<ChildB/>
<ChildC/>
</ChildNode>
<ChildNode>
<ChildA/>
<ChildB/>
<ChildC/>
</ChildNode>
</RootNode>
What I need is a means to insert a new node underneath one of the <ChildNode> elements. However, this requires indexing to specify which <ChildNode> I'd like to add to. So, using a SetValue, I have the following left-hand side of an expression:
/process_data/xmlVar/RootNode/ChildNode[2]/NewNode
and on the right-hand side of the expression:
'test'
However, the above throws an XML parsing error stating that an "invalid XML character was specified". If I simply remove the indexing from the left-hand side to yield:
/process_data/xmlVar/RootNode/ChildNode/NewNode
the SetValue properly adds the node <NewNode> but it does so under the first <ChildNode> - which I understand.
So my question is simply: "How does one index their XML expression properly when trying to dynamically build XML?" I have tried putting both single quotes and double quotes around the index but to no avail.
Thanks in advance.
Views
Replies
Sign in to like this content
Total Likes
XPath is not your friend when it comes to adding nodes. XSLT is not necessarily your friend either but it works.
I built the attached process to insert a third 'ChildNode'
<ChildNode>
<ChildA>A3</ChildA><ChildB>B3</ChildB><ChildC>C3</ChildC>
</ChildNode>
into
<RootNode>
<ChildNode>
<ChildA>A1</ChildA><ChildB>B1</ChildB><ChildC>C1</ChildC>
</ChildNode>
<ChildNode>
<ChildA>A2</ChildA><ChildB>B2</ChildB><ChildC>C2</ChildC>
</ChildNode>
</RootNode>
to produce
<RootNode>
<ChildNode>
<ChildA>A1</ChildA><ChildB>B1</ChildB><ChildC>C1</ChildC>
</ChildNode>
<ChildNode>
<ChildA>A2</ChildA><ChildB>B2</ChildB><ChildC>C2</ChildC>
</ChildNode>
<ChildNode>
<ChildA>A3</ChildA><ChildB>B3</ChildB><ChildC>C3</ChildC>
</ChildNode>
</RootNode
The XSLT goes like this
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="childA">ChildA</xsl:param>
<xsl:param name="childA_text">{$ /process_data/@childNodeA $}</xsl:param>
<xsl:param name="childB">ChildB</xsl:param>
<xsl:param name="childB_text">{$ /process_data/@childNodeB $}</xsl:param>
<xsl:param name="childC">ChildC</xsl:param>
<xsl:param name="childC_text">{$ /process_data/@childNodeC $}</xsl:param>
<xsl:output method="xml" encoding="utf-8"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="RootNode">
<xsl:copy>
<xsl:apply-templates/>
<xsl:if test="position()=last()">
<ChildNode>
<xsl:element name="{$childA}"><xsl:value-of select="$childA_text"/></xsl:element>
<xsl:element name="{$childB}"><xsl:value-of select="$childB_text"/></xsl:element>
<xsl:element name="{$childC}"><xsl:value-of select="$childC_text"/></xsl:element>
</ChildNode>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Steve
Views
Replies
Total Likes
Hi Steve,
Never heard back from you. If you can't help, please let me know.
Besy,
Rob
Views
Replies
Sign in to like this content
Total Likes
Sorry,
Best,
Rob
Sent via BlackBerry from T-Mobile
Views
Replies
Sign in to like this content
Total Likes
You can use insertXmlData operation in our XML Utils component.
Info: http://avoka.dnsalias.com/confluence/display/Public/XML+Utilities+DSC
Download: http://www.avoka.com/avoka/escomponents.shtml
Howard
Views
Replies
Sign in to like this content
Total Likes