We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Matching a simple tag in XSLT

Medium Priority
263 Views
Last Modified: 2013-11-19
This is an easy question (and 500 points because I'm in a real hurry...): I have this XML document that looks like:

<?xml version="1.0" encoding="UTF-8"?>
  <DocRoot xmlns="http://namespace1"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://namespace1
                               http://namespace1/schema1.xsd">
  <Node1>...
...etc.

and I wrote a simple XSLT document like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet    
                            xmlns="http://namespace1"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://namespace1
                               http://namespace1/schema1.xsd">
     <xsl:template match="/">
         <html>
             <head>
                 <title>Tiny Output</title>
             </head>
             <body>
                 <xsl:for-each select="DocRoot">
                     <b>hello</b>
                     <br></br>
                 </xsl:for-each>
             </body>
         </html>
     </xsl:template>
   
</xsl:stylesheet>

The purpose is to jump-start my project by figuring out how to match an arbitrary node (in this case, the DocRoot element of the XML document), but when I process this in oXygen, it does not work: it seems that "DocRoot" was never matched, so there is no "hello" in the html output of the process. Any help will be appreciated!
Comment
Watch Question

Carl TawnSenior Systems and Integration Developer
CERTIFIED EXPERT

Commented:
If you open your XSL in internet explorer you should get a message saying:

   "Reference to undeclared namespace prefix: 'xsl'. Error processing resource "

This is because you are missing the xsl namespace from your xsl:stylesheet tag. It should read:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                            xmlns="http://namespace1"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://namespace1
                               http://namespace1/schema1.xsd">

Author

Commented:
Actually, I do have that xsl namespace definition, but forgot to paste it in the question...it still seem to miss out the part where I actually want to select value from (all the other parts of the output, such as <html>, etc. are there except for the <b>hello</b><br></br> part)...
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
here is your problem

xmlns="http://namespace1"

this is the default namespace in your source XML,
but cannot be the default namespace in your resulttree,
because the html output is that

try in the XSLT
xmlns:n1="http://namespace1"

and address the node like this
<xsl:for-each select="n1:DocRoot">

that will work
cheers
Information Architect
CERTIFIED EXPERT
Top Expert 2006
Commented:
this stylesheet works

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:n1="http://namespace1"
     exclude-result-prefixes="n1">
    <xsl:template match="/">
        <html>
            <head>
                <title>Tiny Output</title>
            </head>
            <body>
                <xsl:for-each select="n1:DocRoot">
                    <b>hello</b>
                    <br></br>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
 </xsl:stylesheet>

note the exclude-result-prefixes="n1"
that is to make sure that the n1 namespace node doesn't make it to the resulttree
you would have a xmlns:n1="http://namespace1" in your output, that is not used

cheers

Geert

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
Okay this works! One more question: suppose there are many nodes like:

<MyRepeatingNode>
   <Subnode1/>
   <OptionalNode1>SomeValue</OptionalNode1>
   ...
</MyRepeatingNode>
<MyRepeatingNode>
   <Subnode1/>
   <OptionalNode1>SomeValue</OptionalNode1>
   ...
</MyRepeatingNode>
<MyRepeatingNode>
   <Subnode1/>
   <OptionalNode1>SomeValue</OptionalNode1>
   ...
</MyRepeatingNode>

What if <OptionalNode1/> appears only in some of the <MyRepeatingNode>s and not others -- how do I ensure that, if <OptionalNode1> is missing, then <xsl:value-of select="ns1:MyRepeatingNode/OptionalNode1"> does not appear in the final output (that is, conform to the minOccurs="0" in the XSD of the output XML...)? I don't want extraneous elements in the final output when it is unnecessary to include them...
Carl TawnSenior Systems and Integration Developer
CERTIFIED EXPERT

Commented:
Something like:

   <xsl:for-each select="MyRepeatingNode[OptionalNode1]">

   </xsl:for-each>

This would only process MyRepeatingNode nodes that have a child OptionalNode1.

Author

Commented:
Actually, I want to process all MyRepeatingNodes, but for some of the MyRepeatingNOdes, I want to suppress the output pf <OptionalNode1> when it doesn't exist within the parent MyRepeatingNode...
Carl TawnSenior Systems and Integration Developer
CERTIFIED EXPERT
Commented:
Ok:

   <xsl:for-each select="MyRepeatingNode">
       <xsl:if test="OptionalNode1">
           <xsl:value-of select="OptionalNode1" />
       </xsl:if>
   </xsl:for-each>
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.