search and replace

F

foolproofplan

Hey everyone. I am running into a problem with unique ids that need to
be compared in two xml files. The actual object name is represented
with its unique id later in the xml file, so i need to do a search on
an id, find its name, and then replace the original id with the name
instead. If this doesn't make much sense, here is an example:

<DBViewer template_id=" .... />
<Fruits type="ObjectLink" >:1170775272:459887139:</Fruits>
</DBViewer>

<excel_database template_id=":324:431:" id=":1170775272:459887139:"
name="banana" />

In this example, the Fruit ObjectLink should be "banana" because it
has the same id as the database below.

I have already been doing xsl transformations on this file, so if that
is possible for this situation, that would be great. How do you guys
reccommend going about this?
 
R

roy axenov

Hey everyone. I am running into a problem with unique ids
that need to be compared in two xml files. The actual
object name is represented with its unique id later in
the xml file, so i need to do a search on an id, find its
name, and then replace the original id with the name
instead. If this doesn't make much sense, here is an
example:

<DBViewer template_id=" .... />

Ouch. That's not particularly well-formed.
<Fruits
type="ObjectLink" >:1170775272:459887139:</Fruits>
</DBViewer>

<excel_database template_id=":324:431:"
id=":1170775272:459887139:" name="banana" />

In this example, the Fruit ObjectLink should be "banana"
because it has the same id as the database below.

You should've posted some code. What precisely your problem
is? Something like this:

<xsl:template match="*[@type='ObjectLink']">
<xsl:copy>
<xsl:apply-templates
select=
"
//excel_database[@id=current()/text()]/@name
"/>
</xsl:copy>
</xsl:template>

....should do the trick.
 
J

Joseph Kesselman

If it really is an XML ID (declared as such in the DTD or schema), you
may be able to speed that up by replacing
//excel_database[@id=current()/text()]/@name
with
id(current())/@name
(Take the value of the current node, do a table lookup to find the
element which carries that id value, take its name attribute.) The
advantage is that this avoids having to search the whole document for
the desired entry; the disadvantage is that unless it's properly
declared it doesn't work.

If you have to use the search approach, you may want to consider
modifying it:
//excel_database[@id=current()][1]/@name
.... assuming that the ID is unique, this generates the same result but
avoids wasting time searching for another instance.

BTW, testing current()/text() checks whether a single text=-node child
has that value -- which may or may not be what you want if there's
markup inside the current() node. If you want the string value of the
whole node, you can just test it directly or use the string() function
(which comes out to the same thing).
 
F

foolproofplan

I had tried using your code:

<xsl:template match="*[@type='ObjectLink']">
<xsl:copy>
<xsl:apply-templates
select=
"
//excel_database[@id=current()/text()]/@name
"/>
</xsl:copy>
</xsl:template>

which works perfectly for the certain xml file I was talking about.

I also tried using it for another one:

<?xml version="1.0" encoding="UTF-8"?>
<EnCapta>
<Document type="Part" id=":1170780883:1282681815:" name="New
Document" >
<FileName>\New Document</FileName>
<Unit/>
<ApplicationData id=":1170780887:48766733:" name="HierarchyApp" >
<ApplicationReference id_ref=":21339045:1265399:" >
<Name>HierarchyApp</Name>
<MajorVersion>0</MajorVersion>
<MinorVersion>0</MinorVersion>
</ApplicationReference>
<Colors template_id=":234334:9087980:" id=":1170780887:2185726:"
name="Colors Galore!" >
<Name type="FixedString" >Colors Galore!</Name>
<Index type="Real" >0</Index>
</Colors>
<Blue template_id=":0:534:" id=":1170780890:1627341938:" name="I'm
Blue" >
<Name type="FixedString" >I'm Blue</Name>
<Index type="Real" >0</Index>
<Parent type="ObjectLink" >:1170780887:2185726:</Parent>
</Blue>
<Green template_id=":12045115:5403534:" id=":
1170780894:1308108165:" name="I'm Green" >
<Name type="FixedString" >I'm Green</Name>
<Index type="Real" >0</Index>
<Parent type="ObjectLink" >:1170780887:2185726:</Parent>
</Green>
<Red template_id=":120045115:534:" id=":1170780900:313735256:"
name="I'm Red" >
<Name type="FixedString" >I'm Red</Name>
<Index type="Real" >0</Index>
<Parent type="ObjectLink" >:1170780887:2185726:</Parent>
</Red>
<Link_Hierarchy template_id=":120888115:534:" id=":
1170780904:1346796842:" name="Link_Hierarchy" >
<Root type="ObjectLink" >:1170780900:313735256:</Root>
</Link_Hierarchy>
<Portal_Hierarchy template_id=":177778115:534:" id=":
1170780908:132006292:" name="Portal_Hierarchy" >
<Root type="ObjectLink" >:1170780887:2185726:</Root>
</Portal_Hierarchy>
</ApplicationData>
</Document>
</EnCapta>

and reworked the code as this:

<xsl:template match="*[@type='ObjectLink']">
<xsl:copy>
<xsl:apply-templates
select="//*[@id=current()/text()]/@name"/>
</xsl:copy>
</xsl:template>

However, nothing is copied into the ObjectLinks.

Am I wrong on using * as a wildcard?
 
J

Joe Kesselman

One immediate reaction: You wrote
> select="//*[@id=current()/text()]/@name"/>

"Find any element in the document whose id attribute's value equals ONE
OF THE TEXT CHILDREN of the current node, and process its name attribute."

I suspect you meant

"Find any element whose id attribute's value equals THE CONTAINED TEXT
VALUE of the current node, and process its name attribute."

which would be written as
select="//*[@id=current()]/@name"/>

(I haven't looked deeply enough to see whether this is actually what's
causing your problem, but it's an important distinction to learn.)
 
A

Andrew

Hey everyone. I am running into a problem with unique ids that need to
be compared in two xml files. The actual object name is represented
with its unique id later in the xml file, so i need to do a search on
an id, find its name, and then replace the original id with the name
instead. If this doesn't make much sense, here is an example:

<DBViewer template_id=" .... />
<Fruits type="ObjectLink" >:1170775272:459887139:</Fruits>
</DBViewer>

<excel_database template_id=":324:431:" id=":1170775272:459887139:"
name="banana" />

In this example, the Fruit ObjectLink should be "banana" because it
has the same id as the database below.

I have already been doing xsl transformations on this file, so if that
is possible for this situation, that would be great. How do you guys
reccommend going about this?

Don't testing it for xml , but possible it can help
-----------
You can use RQ Search and Replace to search and replace HTML code for tags, attribute names, or values.
For example you can change the font size of one font type without affecting any others.
[font size="2" face="Arial"] will be changed to [font size="3" face="Arial"], but tag [font size="2" face="Verdana"] remain the same size="2".
You can delete or change HTML tags, it's attributes or attributes values.
Don't worry about attribute's order in tag - program parsed HTML code and get all attributes and its values properly.
-------------------
homepage - http://www.miraxem.com/rqsr.html

WBR, Andrew




BizTalk Utilities - Frustration free BizTalk Adapters
http://www.topxml.com/biztalkutilities
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top