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-each
getNodes
xsl:choose
xsl:when
xsl:otherwise
这是我尝试过的。所有都放在模板中的内部的<xsl:text>"</xsl:text>
和之后。首先是 XSL 输入、我对所发生事情的总结以及相关的 JSON 输出。</xsl:for-each>
for-each
getNodes
测试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() < 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() < count($pcCap_list/value)" > <!-- happens with both < 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"
}
}
}
那么发生了什么导致管道工作但逗号不工作?为什么第三个元素有时会自己打印?