2

I'm rather new to the world of xml and xslt. What I am wanting to do is use an xslt to return all the error messages generated in an xml file, there are many error messages under each parent.

Here's an example of the XML file:

   <progress_file>
        <read_leg>
            <info>Successfully read face ID 225</info>
            <info>successfully read face ID 226</info>
            <error>unable to read face ID 227</error>
            <error>unable to read face ID 228</error>
        </read_leg>
        <write_leg>
            <info>Successfully created face ID 225</info>
            <info>successfully created face ID 226</info>
            <error>unable to write face ID 227</error>
            <error>unable to write face ID 228</error>
        </write_leg>
    </progress_file>

The XSLT used is:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
      <xsl:for-each select="progress_file/read_leg">
        <xsl:value-of select="error"/>
      </xsl:for-each>
      <xsl:for-each select="progress_file/write_leg">
        <xsl:value-of select="error"/>
      </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

The output only returns the first value from each area. I gather that this is what the logic implies, i.e. "for each write leg, return the error message" and this doesn't mean it checks if there are multiple cases.

I haven't seen anywhere that has multiple attributes with the same name and I haven't come across and XSL element that can work with this, so I'm a bit stuck. Any suggestions on how this is possible?

One further question, is it possible to get line breaks in between the output lines?

Thanks.

2
  • @EeroHelenius Please do not edit OP's code; you don't know if the original is correct. Commented Jul 14, 2014 at 14:17
  • @michael.hor257k: My apologies, and thanks for pointing it out. I was just assuming that there was a typo in the code since it didn't correspond with the sample input. But you're right, it's probably not safe to make such assumptions — I'll know better in the future. Commented Jul 14, 2014 at 14:22

1 Answer 1

3

Here's one option:

Stylesheet

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" version="1.0" encoding="utf-8"/>

  <!-- The XML entity for a line feed -->
  <xsl:variable name="linefeed" select="'&#10;'"/>

  <!-- Match the root node -->
  <xsl:template match="/">
    <!-- Apply templates for all <error> nodes. -->
    <xsl:apply-templates select="progress_file/read_leg/error | progress_file/write_leg/error"/>
  </xsl:template>

  <xsl:template match="error">
    <!-- Concatenate the value of the current node and a line feed. -->
    <xsl:value-of select="concat(., $linefeed)"/>
  </xsl:template>
</xsl:stylesheet>

Output

unable to read face ID 227
unable to read face ID 228
unable to write face ID 227
unable to write face ID 228
Sign up to request clarification or add additional context in comments.

7 Comments

You can shorten your match down to progress_file/*/error assuming he wants all potential error elements under progress_file processed.
"read_leg first and then write_leg" is a misconception. It's irrelevant in what order you select nodes, the resulting node set will always be in document order in XSLT. (BTW, this is true for XSLT 2.0 as well: A single XPath expression will yield a sequence in document order. However, you can build custom-ordered sequences, too.)
@MatthewGreen Just because you can, doesn't mean you should.
@Tomalak: You're absolutely right, thanks for pointing it out. I was thinking of , instead of |.
Thankyou, this outputs the correct data. But the line feed option doesn't work. I've opened the XML in IE and tried using the TryIt editor on W3 schools site link adn all the info appears on one line. Any idea's on why this is the case?
|

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.