XML to XML

R

rjmolesa

I have a gnucash file that I'm trying to transform into an identical
XML file without the invoices.

I've been at this for a while now. The gnucash file is in XML and the
element I'm looking into is:
<gnc:transaction>

I want to ignore those that contain <slot:key>gncInvoice</slot:key>
which is a child of slot which is a child of slots which is a child of
transactions.

Any help you're willing to provide would be greatly appreciated.

Thanks.
 
J

Joe Kesselman

Classic application for XSLT. Start with the identity transformation,
then add a template which matches the ones you want to treat specially
and yields no output. From your description that would be
match="gnc:transaction[transactions/slots/slot/slot:key='gncInvoice']"
with the namespaces declared appropriately in the stylesheet.

(That looks like a somewhat unlikely markup design to me, but since I
haven't played with gnucash at all I'm taking your word for it.)
 
J

Joe Kesselman

Actually, from the Relax-NG schema for gnucash, it looks like it should
be more like
"gnc:transaction[trn:slots/slot/slot:key='gncInvoice']"

with gnc:, trn:, and slot: all bound to the appropriate namespace URIs.

The fact that some of their elements -- eg <slot> -- aren't in any
namespace is probably left over from a pre-namespaces initial design, as
is their now-broken DTD (since DTDs really don't play nicely with
namespaces). Workable, but inelegant. (I'm also really not convinced
they need all those tiny little namespaces, but Oh Well.)
 
T

Thufir

Actually, from the Relax-NG schema for gnucash,
[...]

Heh, this is straight from "100 xml hacks" by oreilly. They specify
relax-NG to do the identity transform as a starting point :)


-Thufir
 
R

rjmolesa

Classic application for XSLT. Start with the identity transformation,
then add a template which matches the ones you want to treat specially
and yields no output. From your description that would be
match="gnc:transaction[transactions/slots/slot/slot:key='gncInvoice']"
with the namespaces declared appropriately in the stylesheet.

(That looks like a somewhat unlikely markup design to me, but since I
haven't played with gnucash at all I'm taking your word for it.)

Thanks I'll be looking at this closer tomorrow. But please speak
plainly and slowly guys, I'm still learning this stuff. This is my
first practical application of XSLT.

The markup is actually:

<gnc:transaction version="2.0">
<!--some other elements-->

<trn:slots>
<!--more elements-->
<slot>
<slot:key>gncInvoice</slot:key> <!--If this appears in any
transactions, i just want to skip it, everything else I want
transformed verbatim-->
<!--more elements-->
</slot>
<!--still more-->
</trn:slots>
<!--more yet-->
</gnc:transaction>
 
P

Pavel Lepin

Michael said:
Joe Kesselman mentioned the identity transformation. I had
to solve a similar problem recently and it was not that
easy to find out the right way.

Perhaps this helps you:

<xsl:template
match="*|comment()|processing-instruction()|@*"
priority="-1">
<xsl:copy>
<xsl:apply-templates
select="*|text()|comment()|processing-instruction()|@*"
/>
</xsl:copy>
</xsl:template>

I'm wondering why are you using an identity transformation
instead of THE identity transformation?
The priority must be set to -1 to let other templates be
considered by the XSLT processor.

Pardon me? I don't believe that's true. Specificity rules
handle all the priority issues in something like 999 cases
out of 1000. In fact, I can't remember using priority
attribute even once, despite more than half my stylesheets
using the identity transformation.
 
J

Joe Kesselman

Pavel said:
Pardon me? I don't believe that's true. Specificity rules
handle all the priority issues in something like 999 cases
out of 1000.

XSLT's specificity rules are actually quite weak compared to similar
systems. They're sufficient for most common cases, as Pavel says, and
for this one in particular, but you will sometimes need to tweak
priority explicitly.

There's nothing inherently wrong with explicitly setting priority as a
safety net, but most of us wouldn't bother in this case.
 
J

Joe Kesselman

Pavel said:
I'm wondering why are you using an identity transformation
instead of THE identity transformation?

The standard version, as it originally appeared in the XSLT
Recommendation (http://www.w3.org/TR/1999/REC-xslt-19991116#copying):

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

node() is a wildcard that matches anything, and since the default axis
is child:: this matches all children. Attributes aren't children, so we
need to explicitly ask for them too.

There are a few minor variants floating around, but this is probably the
simplest.
 

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

Forum statistics

Threads
474,008
Messages
2,570,268
Members
46,867
Latest member
Lonny Petersen

Latest Threads

Top