1

TL;DR - 问题: 在嵌套for-each中我无法正确打印逗号。有四个案例不断重复。我可以想到其他方法来完成工作,但我真的很想知道为什么会这样。

问题:为什么管道可以工作,但逗号不行,为什么有时最后一个元素会自行打印出来?

概述:我正在尝试将包含节点关系的 XML 文档转换为 JSON 格式,以便我可以进行图形可视化。有几种方法可以解决这个问题,我选择从生成节点列表开始。因此,我有一个 XSL 文件,它将 XML 文档转换为节点的 JSON 树结构。

这是 XML 文件的片段:

<?xml version="1.0" ?>
<knowledge_base
  xmlns="http://protege.stanford.edu/xml"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://protege.stanford.edu/xml http://www.enterprise-architecture.org/xml/essentialreportxml.xsd">
  <simple_instance>
    <name>Class181</name>
    <type>Business_Capability</type>
    <own_slot_value>
      <slot_reference>business_capability_level</slot_reference>
      <value value_type="string">3</value>
    </own_slot_value>
    <own_slot_value>
      <slot_reference>realised_by_business_processes</slot_reference>
      <value value_type="simple_instance">Class40041</value>
    </own_slot_value>
    <own_slot_value>
      <slot_reference>supports_business_capabilities</slot_reference>
      <value value_type="simple_instance">Class180</value>
      <value value_type="simple_instance">Class20022</value>
      <value value_type="simple_instance">Class182</value>
    </own_slot_value>
    <own_slot_value>
      <slot_reference>name</slot_reference>
      <value value_type="string">Help Desk Service</value>
    </own_slot_value>
  </simple_instance>
</knowledge_base>

有多种业务能力,它们可以具有作为父母的业务能力,而其他人则可以作为孩子。这是我的 XSL 文档的大部分内容:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0" xpath-default-namespace="http://protege.stanford.edu/xml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xalan="http://xml.apache.org/xslt" xmlns:pro="http://protege.stanford.edu/xml" xmlns:eas="http://www.enterprise-architecture.org/essential" xmlns:functx="http://www.functx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ess="http://www.enterprise-architecture.org/essential/errorview">

  <xsl:template match="knowledge_base">
        <xsl:call-template name="BuildPage"/>
  </xsl:template>

  <xsl:template name="BuildPage">
    <xsl:param name="pageLabel">Business Capability Graph</xsl:param>
    <html>
      <head>
        <title><xsl:value-of select="$pageLabel"></xsl:value-of></title>
        <script src="js/d3.v3.min.js"></script>
        <script type="text/javascript">
          <xsl:text>
          function tree()
            {
            var json=</xsl:text><xsl:call-template name="getJSON" /><xsl:text>;
            console.log(JSON.stringify(json));
            }
        </xsl:text>
        </script>
        </head>
        <body onload="tree();">
          <div id="main"></div>
        </body>
        </html>
  </xsl:template>

  <xsl:template name="getJSON">
    <xsl:text>{ "nodes" : [</xsl:text>
    <!-- Get Business Caps -->
    <xsl:call-template name="getNodes">
      <xsl:with-param name="nodes" select="/node()/simple_instance[type='Business_Capability']" />
    </xsl:call-template>
    <xsl:text>]}</xsl:text>
  </xsl:template>

  <xsl:template name="getNodes">
    <xsl:param name="nodes" />
    <xsl:for-each select="$nodes">
      <xsl:variable name="name" select="own_slot_value[slot_reference='name']/value" />
      <xsl:variable name="id" select="current()/name" />
      <xsl:variable name="level" select="own_slot_value[slot_reference='business_capability_level']/value" />

      <xsl:text>{"name":"</xsl:text><xsl:value-of select="$name" />
      <xsl:text>", "id":"</xsl:text><xsl:value-of select="$id" />
      <xsl:text>", "level":"</xsl:text><xsl:value-of select="$level" />
      <xsl:text>", "data":{</xsl:text>

      <xsl:variable name="pcCap_list" select="own_slot_value[slot_reference='supports_business_capabilities']" />

      <xsl:text>"pcCap":{</xsl:text>
      <xsl:for-each select="/node()/simple_instance[name=$pcCap_list/value]" >
          <xsl:variable name="pos" select="position()" />
              <xsl:text>"id" : "</xsl:text>
              <xsl:value-of select="name" />
              <xsl:text> - pos </xsl:text><xsl:value-of select="$pos" />
              <xsl:text> - count </xsl:text><xsl:value-of select="count($pcCap_list/value)" />
              <xsl:text>"</xsl:text>
      </xsl:for-each>

      <xsl:text>}}}</xsl:text>
      <xsl:if test="position() != count($nodes)">
        <xsl:text>, </xsl:text>
      </xsl:if>

    </xsl:for-each>


  </xsl:template>

</xsl:stylesheet>

在整个文档中,我已成功使用xsl:if test=position() != count()正确添加逗号 (1, 2, 3),但在模板内部除外。我尝试了许多不同的变体,从使用 position()、count()、last()、!=、<、>、=、not(position() = count())、count()-1、count() +1 等,以及 with和语句。我一直在下面看到相同的四种模式(以及 XSL 语法错误和空对象)。for-eachgetNodesxsl:choosexsl:whenxsl:otherwise

这是我尝试过的。所有都放在模板中的内部的<xsl:text>"</xsl:text>和之后。首先是 XSL 输入、我对所发生事情的总结以及相关的 JSON 输出。</xsl:for-each>for-eachgetNodes

测试1:

<xsl:if test="position() != count($pcCap_list/value)" >
  <xsl:text>, </xsl:text>
</xsl:if>

No XSL error.  No JS error.  But only **last element** is printed.

{
"name": "Help Desk Service",
"id": "Class181",
"level": "3",
"data": {
  "pcCap": {
    "id": "Class20022 - pos 3 - count 3"
  }
}
}

测试 2:

<xsl:if test="position() = count($pcCap_list/value)" >
  <xsl:text>, </xsl:text>
</xsl:if>

No XSL error.  JS errors = "Uncaught SyntaxError: Unexpected string report:8" && "Uncaught ReferenceError: tree is not defined report:125".  All three are printed as expected with the comma after the third element.

{
  "name": "Help Desk Service",
  "id": "Class181",
  "level": "3",
  "data": {
    "pcCap": {
      "id": "Class180 - pos 1 - count 3""id": "Class182 - pos 2 - count 3""id": "Class20022 - pos 3 - count 3",

    }
  }
}

测试 3:

<xsl:if test="position() &lt; count($pcCap_list/value)" >
  <xsl:text>, </xsl:text>
</xsl:if>
No XSL error.  No JS error.  Again, only last item is shown.

{
"name": "Help Desk Service",
"id": "Class181",
"level": "3",
"data": {
  "pcCap": {
    "id": "Class20022 - pos 3 - count 3"
  }
}
}

测试 4:

<xsl:if test="position() &lt; count($pcCap_list/value)" > <!-- happens with both &lt; and != -->
  <xsl:text>| </xsl:text>
</xsl:if>

No XSL error.  JS errors = "Uncaught SyntaxError: Unexpected token : report:8" && "Uncaught ReferenceError: tree is not defined report:125".  Prints out as expected, with pipes between the elements.

{
  "name": "Help Desk Service",
  "id": "Class181",
  "level": "3",
  "data": {
    "pcCap": {
      "id": "Class180 - pos 1 - count 3"|"id": "Class182 - pos 2 - count 3"|"id": "Class20022 - pos 3 - count 3"
    }
  }
}

那么发生了什么导致管道工作但逗号不工作?为什么第三个元素有时会自己打印?

4

1 回答 1

0

您最初发布的转换适用于我的 XSL 转换器。我认为您的问题可能与变压器本身有关。我刚刚复制并粘贴了您的 XML 和 XSL,并从 XSLT 获得了所需的输出。

于 2013-07-07T02:46:05.360 回答