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()
在{{for-each
内正确添加逗号(1,2,3), EXCEPT 1}}模板。我尝试了很多不同的变体,从使用position(),count(),last(),!=,&lt;,&gt;,=,not(position()= count()),count() - 1,count ()+1等,以及带有getNodes
和xsl:choose
语句的xsl:when
。我一直看到下面的四种模式(以及XSL语法错误和空对象)。
这是我尝试过的。所有内容都放在xsl:otherwise
模板中内<xsl:text>"</xsl:text>
的{{1}}和</xsl:for-each>
之后。首先是XSL输入,我对发生的事情的总结,&amp;相关的JSON输出。
测试1:
for-each
测试2:
getNodes
测试3:
<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"
}
}
}
测试4:
<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",
}
}
}
那么是什么导致管道工作而不是逗号?为什么第三个元素有时会自行打印?
答案 0 :(得分:0)
您最初发布的转换适用于我的XSL转换器。我认为你的问题可能与变压器本身有关。我只是复制并粘贴了你的XML和XSL,并从XSLT获得了所需的输出。