简体   繁体   中英

XSLT for an XML document with arbitrary tags

Just to clarify the title, I have an XML document that looks like the following:

<group>
  <starter>Start</starter>
  <backup1>Backup1</backup1>
</group>
<group>
  <starter>Another starter</starter>
  <backup1>Backup1</backup1>
  <backup2>Backup2</backup2>
  <backup3>Backup3</backup3>
  <reserve>Reserve</reserve>
</group>

So each group can have any number of <backupN> tags. I need to make sure my XSLT grabs all of them and renames them to "backup_n". Normally my XSLT would apply something in line with the following:

<xsl:for-each select="group/backup">

and loop around that xpath selection. That clearly won't work as even if there is only 1 backup, it's still named <backup1> and there can also be an arbitrary amount of <backupN> tags.

What's the best way to loop around arbitrary tags like this? I am using XSLT 1.0, so can't really use any XSLT 2.0 greatness.

If you want all the elements whose name starts with backup you can use

<xsl:for-each select="group/*[starts-with(local-name(), 'backup')]">

but depending on exactly what kind of output you're trying to produce it may be cleaner to do it in terms of template matching rather than for-each .

If you specifically want to restrict to elements whose name is "backup" followed by a number (excluding things like backuptype , for example) then you can add to the predicate

group/*[starts-with(local-name(), 'backup')
    and number(substring(local-name(), 7)) = number(substring(local-name(), 7))]

(this looks odd but the trick is that if substring(local-name(), 7) is not a valid number then the test becomes NaN = NaN which is always false - NaN does not equal anything, not even itself).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM