我的XSLT-Stylesheet有问题。我有一个包含多个程序集的XML文档。每个组件都有一个唯一的项目编号。程序集可以包含其他程序集作为位置,但XML文档具有如下平面结构:
<?xml version="1.0" encoding="ISO-8859-1"?>
<PartsCatalog Version="1.0">
<Description><![CDATA[asdsadasdadad ]]></Description>
<Assembly Item="0000 " Plate=" " Class=" ">
<Description Lang=" DE"><![CDATA[Main assembly]]></Description>
<Description Lang=" EN"><![CDATA[Main assembly]]></Description>
<Description Lang=" FR"><![CDATA[Main assembly]]></Description>
<Description Lang=" IT"><![CDATA[Main assembly]]></Description>
<Description Lang=" RU"><![CDATA[Main assembly]]></Description>
<Position PositionNumber=" 10" Item="9284424 " Plate="000020 " Class=" ">
<Quantity Unit="st "> 1,0000</Quantity>
<Serie From=" " To=" "></Serie>
<Characteristic><![CDATA[ ]]></Characteristic>
<SparePartFlag><![CDATA[00]]></SparePartFlag>
<Description Lang=" DE"><![CDATA[aaaaaa ]]></Description>
<Description Lang=" EN"><![CDATA[aaaaaa ]]></Description>
<Description Lang=" FR"><![CDATA[aaaaaa ]]></Description>
<Description Lang=" IT"><![CDATA[aaaaaa ]]></Description>
<Description Lang=" RU"><![CDATA[ ]]></Description>
</Position>
<Position PositionNumber=" 20" Item="9207826 " Plate="104300 " Class=" ">
<Quantity Unit="st "> 1,0000</Quantity>
<Serie From=" " To=" "></Serie>
<Characteristic><![CDATA[10.00-20 PR16 ]]></Characteristic>
<SparePartFlag><![CDATA[00]]></SparePartFlag>
<Description Lang=" DE"><![CDATA[8 GELAENDEREIFEN ]]></Description>
<Description Lang=" EN"><![CDATA[8 OFFROAD TIRES ]]></Description>
<Description Lang=" FR"><![CDATA[8 PNEUS TOUT-TERRAIN ]]></Description>
<Description Lang=" IT"><![CDATA[8 PNEUMATICI FUORI STRADA ]]></Description>
<Description Lang=" RU"><![CDATA[ ]]></Description>
</Position>
<Position PositionNumber=" 30" Item="9178702 " Plate="104280 " Class=" ">
<Quantity Unit="st "> 1,0000</Quantity>
<Serie From=" " To=" "></Serie>
<Characteristic><![CDATA[MH 3 ]]></Characteristic>
<SparePartFlag><![CDATA[00]]></SparePartFlag>
<Description Lang=" DE"><![CDATA[ZWISCHENRING ]]></Description>
<Description Lang=" EN"><![CDATA[INTERMEDIATE RING ]]></Description>
<Description Lang=" FR"><![CDATA[ENTRETOISE ]]></Description>
<Description Lang=" IT"><![CDATA[ANELLO DISTANZIATORE ]]></Description>
<Description Lang=" RU"><![CDATA[ÏÐÎÊËÀÄÎ×ÍÎÅ ÊÎËÜÖÎ ]]></Description>
</Position>
<Assembly Item="9284424 " Plate="000020 " Class="11100301 ">
<Description Lang=" DE"><![CDATA[aaaaa ]]></Description>
<Description Lang=" EN"><![CDATA[aaaaa ]]></Description>
<Description Lang=" FR"><![CDATA[aaaaa ]]></Description>
<Description Lang=" IT"><![CDATA[aaaaa ]]></Description>
<Description Lang=" RU"><![CDATA[ ]]></Description>
<Image PositionFrom=" 0">187994</Image>
<Position PositionNumber=" 100" Item="9284426 " Plate="201000 " Class="110000 ">
<Quantity Unit="st "> 1,0000</Quantity>
<Serie From=" " To=" "></Serie>
<Characteristic><![CDATA[ ]]></Characteristic>
<SparePartFlag><![CDATA[20]]></SparePartFlag>
<Description Lang=" DE"><![CDATA[OBERWAGEN ]]></Description>
<Description Lang=" EN"><![CDATA[UPPERCARRIAGE ]]></Description>
<Description Lang=" FR"><![CDATA[TOURELLE ]]></Description>
<Description Lang=" IT"><![CDATA[TORRETTA ]]></Description>
<Description Lang=" RU"><![CDATA[ÏÎÂÎÐÎÒÍÀß ÏËÀÒÔÎÐÌÀ ]]></Description>
</Position>
<Position PositionNumber=" 200" Item="9281013 " Plate="102000 " Class="110000 ">
<Quantity Unit="st "> 1,0000</Quantity>
<Serie From=" " To=" "></Serie>
<Characteristic><![CDATA[ ]]></Characteristic>
<SparePartFlag><![CDATA[20]]></SparePartFlag>
<Description Lang=" DE"><![CDATA[UNTERWAGEN 2PKT. ]]></Description>
<Description Lang=" EN"><![CDATA[UNDERCARRIAGE 2PTS. ]]></Description>
<Description Lang=" FR"><![CDATA[CHASSIS 2PTS. ]]></Description>
<Description Lang=" IT"><![CDATA[CARRO 2STAB. ]]></Description>
<Description Lang=" RU"><![CDATA[ ]]></Description>
</Position>
</Assembly>
识别子装配的唯一方法是项目编号。 我想使用jsTree jquery插件将XML显示为树结构。 因此我需要一个像这样的HTML输出:
<div id="jsTree">
<ul>
<li>0001 | Main assembly
<ul>
<li>1111 | Sub assembly 1</li>
<li>2222 | Sub assembly 2</li>
<li>3333 | Sub assembly 3</li>
</ul>
</li>
</ul>
</div>
到目前为止,我尝试使用与我的问题类似的许多问题的答案,但没有任何效果。谁能帮我?提前谢谢!
问候 B0R0H
答案 0 :(得分:1)
您需要使用键,以便每个程序集都可以(递归地)将模板应用于其组件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="kAssy" match="Assembly" use="@Item" />
<xsl:template match="/PartsCatalog">
<div id="jsTree">
<ul>
<xsl:apply-templates select="Assembly[Description='Main assembly']"/>
</ul>
</div>
</xsl:template>
<xsl:template match="Assembly">
<li>
<xsl:value-of select="@Item"/>
<xsl:text> | </xsl:text>
<xsl:value-of select="Description"/>
<xsl:variable name="mySubs" select="key('kAssy', Position/@Item)" />
<xsl:if test="$mySubs">
<ul>
<xsl:apply-templates select="$mySubs"/>
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
基本答案是你需要以正常的方式使用xsl:apply-templates通过数据进行自上而下的递归下降,但有一个例外:而不是处理XML树中节点的物理子节点,你需要处理它的逻辑孩子。所以不要写
<xsl:apply-templates select="child::node()"/>
像往常一样,你写了
<xsl:apply-templates select="//Assembly[@Item = current()/Position/@Item]"/>
然后下一个阶段就是你可以使用密钥来优化它,如michael.hor257k所描述的(如果你使用像Saxon-EE这样自动进行优化的处理器,则不需要)。
答案 2 :(得分:0)
感谢您的帮助! :)刚刚找到问题的解决方案。我会将其发布给其他(也许)类似问题的人。这个对我有用:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="html" encoding="utf-8"/>
<xsl:variable name="lang-all" select="distinct-values(//Description/@Lang)"/>
<xsl:template match="/">
<xsl:variable name="doc" select="."/>
<xsl:for-each select="$lang-all">
<xsl:variable name="lang" select="."/>
<xsl:for-each select="$doc">
<xsl:variable name="filename_index" select="concat('output/',$lang,'/','index','.html')"/>
<xsl:variable name="jstree">
<xsl:call-template name="build-list">
<xsl:with-param name="lang" select="$lang" />
<xsl:with-param name="node" select="PartsCatalog/Assembly[1]" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$filename_index"/>
<xsl:result-document href="{$filename_index}">
<html>
<head>
<meta charset="utf-8"/>
<title>ETK</title>
<script src="../0jquery/jquery-ui-1.10.3/jquery-1.9.1.js"/>
<script src="../0jquery/jquery-ui-1.10.3/ui/jquery-ui.js"/>
<script src="../0dropdown/jquery.easydropdown.min.js"/>
<script src="../0jstree/dist/jstree.min.js"/>
<link rel="stylesheet" href="../0jquery/jquery-ui-themes-1.10.3/themes/smoothness/jquery-ui.css"/>
<link rel="stylesheet" href="../0jstree/dist/themes/default/style.min.css" />
<link rel="stylesheet" href="../0dropdown/themes/easydropdown.css" type="text/css"/>
<link rel="stylesheet" href="../0css/style.css" type="text/css"/>
</head>
<body>
<div class="head">
<div class="innertube_head">
<h1>ETK</h1>
</div>
</div>
<div class="left">
<div class="jstree_header">
<xsl:value-of select="PartsCatalog/Description"/>
</div>
<div class="innertube_left" id="jstree">
<xsl:copy-of select="$jstree" />
</div>
</div>
<div class="center">
<div class="center_top"/>
<div class="center_bottom"/>
</div>
<div class="right">
<div class="3d_frame"></div>
<div class="innertube_right">
<select id="countries" class="dropdown">
<option value="#">Change language</option>
<option value="../{$lang-all[1]}/index.html">german</option>
<option value="../{$lang-all[2]}/index.html">english</option>
<option value="../{$lang-all[3]}/index.html">french</option>
<option value="../{$lang-all[4]}/index.html">italian</option>
<option value="../{$lang-all[5]}/index.html">russian</option>
</select>
<script>
$('#countries').bind('change', function () {
var url = $(this).val();
if (url != '') {
window.location = url;
}
return false;
});
</script>
</div>
</div>
<script>
$(function () {
// 6 create an instance when the DOM is ready
$('#jstree').jstree();
// 7 bind to events triggered on the tree
$('#jstree').on("changed.jstree", function (e, data) {
console.log(data.selected);
});
// 8 interact with the tree - either way is OK
$('button').on('click', function () {
$('#jstree').jstree(true).select_node('child_node_1');
$('#jstree').jstree('select_node', 'child_node_1');
$.jstree.reference('#jstree').select_node('child_node_1');
});
});
</script>
</body>
</html>
</xsl:result-document>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="Assembly">
<xsl:apply-templates select="Position"/>
</xsl:template>
<xsl:template match="Position">
<xsl:param name="lang"/>
<TR>
<TD>
<xsl:value-of select="normalize-space(@PositionNumber)"/>
</TD>
<TD>
<xsl:value-of select="normalize-space(Description[@Lang=$lang])"/>
</TD>
<TD>
<xsl:value-of select="normalize-space(@Item)"/>
</TD>
<TD>
<xsl:value-of select="normalize-space(Quantity)"/>
</TD>
<TD>
<xsl:value-of select="normalize-space(Quantity/@Unit)"/>
</TD>
</TR>
</xsl:template>
<xsl:template name="build-list">
<xsl:param name="node"></xsl:param>
<xsl:param name="lang"></xsl:param>
<ul>
<xsl:for-each select="$node/Position">
<xsl:variable name="item" select="@Item" />
<xsl:if test="count(//Assembly[@Item = $item]) != 0">
<li>
<xsl:value-of select="normalize-space(@Item)"/> | <xsl:value-of select="normalize-space(Description[@Lang=$lang])"/>
<xsl:call-template name="build-list">
<xsl:with-param name="node" select="//Assembly[@Item = $item]" />
<xsl:with-param name="lang" select="$lang" />
</xsl:call-template>
</li>
</xsl:if>
<xsl:if test="count(//Assembly[@Item = $item]) = 0">
<li><xsl:value-of select="normalize-space(@Item)"/> | <xsl:value-of select="normalize-space(Description[@Lang=$lang])"/></li>
</xsl:if>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>