TL; DR - 問題:在嵌套for-each
中,我無法正確打印逗號。有四種情況不斷重複。爲了完成工作,我還可以考慮其他方法,但我真的很想知道爲什麼這樣做是行事方式。爲什麼逗號在嵌套for-each的XSL中無法按預期工作?
問題:爲什麼管道工作,但不是逗號,爲什麼最後一個元素有時自己打印出來?
概述:我試圖將包含節點關係的XML文檔轉換爲JSON格式,以便我可以執行圖形可視化。有幾種方法可以解決這個問題,我通過生成節點列表來選擇開始。所以,我有一個將XML文檔轉換爲節點的JSON樹結構的XSL文件。
下面是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()
在getNodes
模板內for-each
內適當加逗號(1,2,3),EXCEPT爲。我已經嘗試了很多不同的變體,從使用position(),count(),last(),!=,<,>,=,not(position()= count()),count() - 1,count() +1等,以及xsl:choose
與xsl:when
和xsl:otherwise
聲明。我繼續看到下面的四種模式(以及XSL語法錯誤和空對象)。
這是我試過的。全部放置在getNodes
模板中的內部for-each
的<xsl:text>"</xsl:text>
和</xsl:for-each>
之後。首先是XSL輸入,我發生了什麼事情的總結,&相關的JSON輸出。
測試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"
}
}
}
那麼,什麼是對,導致管道工作,但不是逗號去?爲什麼第三個元素有時自己打印?