0

I have the following XML and I want to get only the element names that start with "MBH":

<?xml version="1.0" encoding="UTF-8"?> <GenericRecs> <GenericRecord> <record> <MBH1/> </record> <record> <BAL1/> </record> <record> <MBH2/> </record> <record> <BAL2/> </record> <record> <PAY2/> </record> <record> <MBH3/> </record> <record> <BAL3/> </record> <record> <PAY3/> </record> </GenericRecord> </GenericRecs> 

I have the following XSLT:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" version="1.0"> <xsl:variable name="x" select="ext:node-set(substring(local-name(//record/child::*),1,3)='MBH')"/> <xsl:variable name="mbh"> <xsl:for-each select="$x"> <item> <xsl:copy> <xsl:value-of select="local-name(.)"/> </xsl:copy> </item> </xsl:for-each> </xsl:variable> <xsl:template match="/"> <xsl:apply-templates select="$mbh"/> </xsl:template> </xsl:stylesheet> 

But all I get is an error "Description: Can not convert #RTREEFRAG to a NodeList!" I am using EXSLT but I do not understand why I would get that error.

2
  • From what I see none of the complicated things you do is necessary. It looks more like you're digging yourself into a hole there. Commented Sep 7, 2012 at 7:14
  • you are right, sometimes I just think to complicated Commented Sep 7, 2012 at 7:38

1 Answer 1

1

I have the following XML and I want to get only the element names that start with "MBH":

What's wrong with

<xsl:apply-templates select="//record/*[starts-with(name(), 'MBH')]" /> 

?

A few notes:

  • Use name() rather than local-name() whenever possible. There are no namespaces in your input so there is no difference between them anyway.
  • the child:: axis is the default. child::* is equivalent to *.
  • If you can do anything about it, change the input. Having <xyz1> through <xyz3> is not very clever, unless <xyz3> actually is completely different from <xyz1> (instead of merely being "the third <xyz>").
    In that case <xyz num="1"> would be sensible. If they are completely different, they should not have a similar name.
Sign up to request clarification or add additional context in comments.

5 Comments

Hello Tomalak, thank you for getting me into the right direction. I found your apply-templates only returns "true" for the found elements. I changed it to <xsl:template match="//record/*[starts-with(name(), 'MBH')]"> <xsl:value-of select="name()"/> </xsl:template> and it works well.
@Peter Glad I helped, but I have a gut feeling that you're still doing it wrong. Why are you using node-set() at all? What are you trying to achieve?
no, no, it looks much simpler now: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="text()"/> <xsl:template match="//record/*[starts-with(name(), 'MBH')]"> <xsl:value-of select="name()"/> </xsl:template> </xsl:stylesheet>
it only gives me a string of the 3 MBH... elements but that is fine.
@Peter: Ah, I see. Yeah that's not looking too bad.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.