我正在尝试构建一个组织结构图,我想我可能会尝试将我的数据转换为树状结构,如D3.js示例http://mbostock.github.io/d3/talk/20111018/tree.html
我有一个输入文件,它是从MS Access数据库中的查询生成的。 XML看起来像这样......
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Query1.xsd" generated="2015-06-25T15:35:33">
<Query1>
<title>CEO</title>
<reportsTo>1</reportsTo>
<ID>1</ID>
</Query1>
<Query1>
<title>Director of Operations</title>
<reportsTo>1</reportsTo>
<ID>2</ID>
</Query1>
<Query1>
<title>Human Resources Manager</title>
<reportsTo>2</reportsTo>
<ID>3</ID>
</Query1>
</dataroot>
我想要的输出看起来像这样...
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee title="CEO" reportsTo="1" id="1">
<employee title="Director of Operations" reportsTo="1" id="2">
<employee title="Human Resources Manager" reportsTo="2" id="3"></employee>
</employee>
</employee>
</employees>
这里重要的是员工之间的关系。我(想)我需要嵌套元素。 Access数据库的输出非常平坦,但它仍然具有员工ID号,以及与每个员工经理相对应的“reportsTo”号码。如果员工2向员工1报告,那么他们应该嵌套在员工1下面。(我已经为只报告自己的CEO提出了一个特例。)
一旦我得到这个结构,我应该很容易编写一个xslt来从我的输出XML转到D3.js的JS输入结构。看起来应该是这样......
var treeData = [
{
"name": "CEO",
"parent": "null",
"children": [
{
"name": "Director of Operations",
"parent": "Top Level",
"children": [
{
"name": "Human Resources Manager",
"parent": "Level 2: A"
}
]
}
]
}
];
目前,我编写了一个Python脚本来读取我的输入XML,我正在努力让它生成输出XML。
但我觉得我错过了一些东西。我可以写一个xslt直接从输入xml到输出xml文件吗?或者甚至直接从输入xml文件直接到JS输出?
也许我在“代码”解决方案方面一直在考虑太多。如何在不使用我的python脚本的情况下在xslt中执行此操作?
答案 0 :(得分:1)
首先让我们忽略循环问题,让我们假设我们知道组织树的根是$ boss(它可能是第一个雇员,或ID = 1的那个,或者reportTo = ID的那个)。
定义一个键
<xsl:key name="k" match="Query1" use="reportsTo"/>
模板规则:
<xsl:template match="Query1">
<employee title="{title}" reportsTo="{reportsTo}" ID="{ID}">
<xsl:apply-templates select="key('k', ID)"/>
</employee>
</xsl:template>
现在你可以用
来解决问题了<xsl:apply-templates select="$boss"/>
唯一剩下的问题是,如果您的数据中有周期,则会无限期地递归。您的数据确实有一个周期:首席执行官向自己报告。也可能有其他周期。您可以将CEO作为一个特例处理,或者您可以添加逻辑来检测一般情况下的周期;这基本上是通过将参数传递给给出祖先员工列表的模板来完成的。但是在这个阶段,使用XSLT 2.0比使用1.0开始变得容易得多,而你还没有说出你使用的是什么。