1

I've got an XML file which looks somehow like this:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="http://url/stylesheet.xsl"?>

<first xmlns="http://www.loc.gov/zing/srw/">
 <element1>And</element1>
 <e2>I said</e2>
 <e3>
  <e4>
   <mods version="3.0" 
   xmlns:bla="http://www.w3.org/1999/xlink" 
   xmlns:bla2="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns="http://www.loc.gov/mods/v3" 
   xsi:schemaLocation="http://www.loc.gov/mods/v3">                                                        
    <f1>What about</f1>
    <f2>Breakfast at Tiffany's</f2>
   </mods>
  </e4>
 </e3>
</first>

On the other hand I have an XSL-file to grab the elements via XPath:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n="http://www.loc.gov/zing/srw/"
xmlns:o="http://www.loc.gov/mods/v3">

   <xsl:template match="/">
    <html><head></head><body>
     <xsl:value-of select="n:first/n:e2"/>
    </body></html>
   </xsl:template>
</xsl:stylesheet>

With this I can fetch the element e2 saying I said but I have problems to access element f4 saying Breakfast at Tiffany's . Does XPath assume that the element f4 has two namespaces (the default namespace xmlns="http://www.loc.gov/zing/srw/" declared in the root element first and the namespace of the element mods xmlns="http://www.loc.gov/mods/v3") or is the mods namespace xmlns="http://www.loc.gov/mods/v3" the only namespace for all childelements of the mods element? And can I actually access the element e2 easier without the declaration of prefixes in my xsl-file? I am just starting to use XML/XSL, so I hope my question is clear.

2 Answers 2

1

The following XPath expression should work:

n:first//o:f2

The mods element is in the o namespace, defining prefixes for other namespaces does not change it. Its children inherit the namespace.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that already helped me. So the one namespace attached to the next parent defines the namespace for all child elements within it.
@JJJ: Unless they override it by using a prefix or another xmlns.
1

Just to expand on choroba's answer - because mod resets the default xmlns, you will need to adapt your namespace alias accordingly, i.e. the full walk is:

 <xsl:value-of select="/n:first/n:e3/n:e4/o:mods/o:f2/text()"/>

If you omit the namespaces in your xslt, you can use local-name() to check for nodes irrespective of their namespace (which is not recommended in this case, since as you can see, this becomes very verbose)

 <xsl:value-of select="/*[local-name()='first']/*[local-name()='e3']
                       /*[local-name()='e4']/*[local-name()='mods']
                       /*[local-name()='f2']/text()"/>

You can remove the aliases from the output document (html) by adding exclude-result-prefixes="n o" to your xsl:stylesheet

I would advise against getting into the habit of using '//' as can cause unnecessary processing by the parser on large documents.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.