views:

103

answers:

3

I'm trying to query an xml file using the following xslt:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
                xmlns:bpmn="http://dkm.fbk.eu/index.php/BPMN_Ontology"&gt;

<!-- Participants -->
<xsl:template match="/">
<html>
    <body>
<table>
          <xsl:for-each select="Package/Participants/Participant">
                  <tr>
                    <td><xsl:value-of select="ParticipantType" /></td>
                    <td><xsl:value-of select="Description" /></td>
                  </tr>
          </xsl:for-each>
    </table>
       </body>
    </html>
</xsl:template> 
</xsl:stylesheet>

Here's the contents of the xml file:

    <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet type="text/xsl" href="xpdl2bpmn.xsl"?>
        <Package xmlns="http://www.wfmc.org/2008/XPDL2.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="25ffcb89-a9bf-40bc-8f50-e5afe58abda0" Name="1 price setting" OnlyOneProcess="false">
      <PackageHeader>
        <XPDLVersion>2.1</XPDLVersion>
        <Vendor>BizAgi Process Modeler.</Vendor>
        <Created>2010-04-24T10:49:45.3442528+02:00</Created>
        <Description>1 price setting</Description>
        <Documentation />
      </PackageHeader>
      <RedefinableHeader>
        <Author />
        <Version />
        <Countrykey>CO</Countrykey>
      </RedefinableHeader>
      <ExternalPackages />
      <Participants>
        <Participant Id="008af9a6-fdc0-45e6-af3f-984c3e220e03" Name="customer">
          <ParticipantType Type="RESOURCE" />
          <Description />
        </Participant>
        <Participant Id="1d2fd8b4-eb88-479b-9c1d-7fe6c45b910e" Name="clerk">
          <ParticipantType Type="ROLE" />
          <Description />
        </Participant>
      </Participants>
</Package>

Despite, the simple pattern, the foreach doesn't work. What is wrong with Package/Participants/Participant ? What do I miss here? Is there something about namespaces that I don't get?

Thanks a lot!

A: 

Your XML file has a default namespace. You need to match that explicitly in your XSLT:

<xsl:for-each
  xmlns:xpdl2="http://www.wfmc.org/2008/XPDL2.1"
  select="xpdl2:Package/xpdl2:Participants/xpdl2:Participant">
        <tr>
          <td><xsl:value-of select="xpdl2:ParticipantType" /></td>
          <td><xsl:value-of select="xpdl2:Description" /></td>
        </tr>
</xsl:for-each>
bkail
+3  A: 

There are a number of problems in your code:

  1. The elements of the XML document are in a default namespace but the match patterns (and select expressions) in the XSLT code use elements in "no namespace".

  2. The two <xsl:value-of> instructions try to produce the value of ParticipantType and Description, but these two elements dont have any value.

The second problem needs that the XML document be changed so that ParticipantType and Description have values.

The first problem is a subject of many FAQs and has a well-known solution: The namespace that is default in the XML document -- must also be defined and associated with a prefix in the XSLT stylesheet. This prefix must be used when referencing names from the XML document.

After this correction the XSLT stylesheet will look like the following:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:bpmn="http://dkm.fbk.eu/index.php/BPMN_Ontology"
 xmlns:xp="http://www.wfmc.org/2008/XPDL2.1"
>

<!-- Participants -->
<xsl:template match="/">
<html>
 <body>
  <table>
   <xsl:for-each select="xp:Package/xp:Participants/xp:Participant">
     <tr>
       <td><xsl:value-of select="xp:ParticipantType" /></td>
       <td><xsl:value-of select="xp:Description" /></td>
     </tr>
   </xsl:for-each>
  </table>
 </body>
</html>
</xsl:template>
</xsl:stylesheet>

Notice the newly-defined namespace with the xp: prefix.

The output now is:

<html xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:bpmn="http://dkm.fbk.eu/index.php/BPMN_Ontology" xmlns:xp="http://www.wfmc.org/2008/XPDL2.1"&gt;
    <body>
        <table>
            <tr>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
            </tr>
        </table>
    </body>
</html>

You just need to solve Problem 1 and the <td>s will not be empty.

Dimitre Novatchev
+1 for covering both problems.
Mark Byers
A: 

Dimitre and bkail have pointed out the problems in your XSLT and also that the <ParticipantType> and <Description> elements are empty.

But I'm wondering if perhaps you meant to get not the (empty) value of the <ParticipantType> element but instead of its Type attribute (eg, "RESOURCE" and "ROLE"). In that case, you would need to change your match pattern to specify the attribute:

<td><xsl:value-of select="xp:ParticipantType/@Type" /></td

Since the <Description> elements in your sample have neither element content nor any attributes, there's nothing that can be plucked out of the source to appear in the result file. But do be aware that "content" is a specific reference to the text between an element's start- and end-tags, and sometimes you want to include the value for one of the element's attributes, not "content."

Roger_S

Roger_S