【问题标题】:xslt broken: pattern does not matchxslt 损坏:模式不匹配
【发布时间】:2011-02-11 21:38:05
【问题描述】:

我正在尝试使用以下 xslt 查询 xml 文件:

<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">

<!-- 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>

这是xml文件的内容:

    <?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>

尽管有简单的模式,但 foreach 不起作用。 Package/Participants/Participant 有什么问题?我在这里想念什么?命名空间有什么我不明白的地方吗?

非常感谢!

【问题讨论】:

  • 好问题 (+1)。请参阅我的答案以获得完整的解决方案,该解决方案描述了代码中的两个问题并展示了如何解决它们。 :)

标签: xml xslt foreach pattern-matching


【解决方案1】:

Dimitre 和 bkail 指出了您的 XSLT 中的问题,并且 &lt;ParticipantType&gt;&lt;Description&gt; 元素是空的。

但我想知道您是否打算获取&lt;ParticipantType&gt; 元素的(空)值,而不是其Type 属性(例如,“RESOURCE”和“ROLE”)。在这种情况下,您需要更改匹配模式以指定属性:

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

由于您的示例中的&lt;Description&gt; 元素既没有元素内容也没有任何属性,因此无法从源中提取任何内容以显示在结果文件中。但请注意,“内容”是对元素开始标签和结束标签之间文本的特定引用,有时您希望包含元素属性之一的值,而不是“内容”。

罗杰_S

【讨论】:

    【解决方案2】:

    您的代码中存在许多问题

    1. XML 文档的元素位于默认命名空间中,但 XSLT 代码中的匹配模式(和选择表达式)使用“无命名空间”中的元素。

    2. 两个&lt;xsl:value-of&gt; 指令试图产生ParticipantTypeDescription 的值,但是这两个元素没有任何值。

    第二个问题需要更改 XML 文档,以便 ParticipantTypeDescription 具有值。

    第一个问题是许多常见问题解答的主题,并且有一个众所周知的解决方案:XML 文档中的默认名称空间——也必须在 XSLT 中定义并与前缀相关联样式表。引用 XML 文档中的名称时必须使用此前缀。

    修正后的 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"
     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>
    

    注意带有xp:前缀的新定义的命名空间。

    现在的输出是

    <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">
        <body>
            <table>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
            </table>
        </body>
    </html>
    

    您只需要解决问题 1&lt;td&gt;s 不会为空。

    【讨论】:

    • 太棒了!!几年来,我一直在努力理解命名空间,并且一直在伪造 XSLT 以生成在每个节点上匹配和选择的 HTML 电子邮件; match="*[name()='TagName']" 而这个例子简直是一分钱一分货!!
    • @user1244215,你和这个问题有什么关系?这个命名空间是原始问题中 OP 提供的 XML 文档和代码的一部分。
    【解决方案3】:

    您的 XML 文件有一个默认命名空间。您需要在 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多