我有一个xml结构。在每个list()中每个position()的xslt模板中,我需要找到属性@out = 1的位置, 然后我需要使用positon的@pid属性创建一个属于它的类别的树结构。
<?xml version="1.0" encoding="ISO-8859-1"?>
<Good id = "2196">
<lists>
<list num="1050" id = "2531" description="Список оборудования и материалов двойного назначения и соответствующих технологий, применяемых в ядерных целях">
<part num="1">
<pos isKey="0" id="2532" pid="2531" description="Раздел 1. Промышленное оборудование" />
<pos num="1.2." isKey="0" id="2554" pid="2532" description="Испытательное и производственное оборудование" />
<pos num="1.2.6." isKey="0" id="2591" pid="2554" description="Системы для вибрационных испытаний, оборудование и компоненты, такие, как:" />
<pos num="1.2.6.1." isKey="1" id="2592" pid="2591" description="Электродинамические системы для вибрационных испытаний" />
<pos num="1.2.6.4." isKey="1" id="2595" pid="2591" description="Конструкции для крепления испытуемой детали и электронные блоки" />
</part>
</list>
<list num="1090" id = "3029" description="Список оборудования, материалов и технологий, которые могут быть использованы при создании ракетного оружия">
<part num="2">
<pos isKey="0" id="3033" pid="3029" description="КАТЕГОРИЯ II" />
<pos isKey="0" id="3040" pid="3033" description="Раздел 9. Измерительное, навигационное и пеленгаторное оборудование и системы" />
<pos isKey="0" id="3041" pid="3033" description="Раздел 10. Системы управления полетом" />
<pos isKey="0" id="3043" pid="3033" description="Раздел 12. Оборудование для обеспечения пуска" />
<pos isKey="0" id="3046" pid="3033" description="Раздел 15. Испытательные системы и оборудование" />
<pos num="9.2." isKey="0" id="3333" pid="3040" description="Испытательное и производственное оборудование" />
<pos num="9.2.1." isKey="0" id="3334" pid="3333" description="Производственное, испытательное.." />
<pos num="9.2.1.2" isKey="0" id="3339" pid="3334" description="Испытательное оборудование для инерциальной аппаратуры:" />
<pos num="9.2.1.2.3." isKey="1" id="3342" pid="3339" description="Испытательный стенд стабилизирующего элемента ИИБ;" />
<pos num="9.2.1.2.5." isKey="1" id="3344" pid="3339" description="Установка для проверки и настройки гироскопа;" />
<pos num="9.2.1.2.9." isKey="1" id="3348" pid="3339" description="Центрифуга для проверки подшипников (опор) гироскопа;" />
<pos num="9.2.1.2.10." isKey="1" out="1" id="3349" pid="3339" description="Установка для осевой регулировки акселерометра;" />
<pos num="9.2.1.2.11." isKey="1" id="3350" pid="3339" description="Установка для проверки акселерометра" />
<pos num="9.2.2." isKey="0" id="3351" pid="3333" description="Испытательное, калибровочное и регулировочное оборудование:" />
<pos num="9.2.2.3." isKey="1" id="3354" pid="3351" description="Динамические моделирующие стенды/столы вращения)" />
<pos num="9.2.2.4." isKey="1" id="3355" pid="3351" description="Поворотные столы" />
<pos num="9.2.2.5." isKey="1" id="3356" pid="3351" description="Центрифуги, способные создавать ускорения более 100 g" />
<pos num="10.2." isKey="0" id="3373" pid="3041" description="Испытательное и производственное оборудование" />
<pos num="10.2.1." isKey="1" id="3374" pid="3373" description="Испытательное, калибровочное и регулировочное оборудование" />
<pos num="12.1." isKey="0" id="3399" pid="3043" description="Оборудование, сборочные единицы и комплектующие" />
<pos num="12.1.1." isKey="1" id="3400" pid="3399" description="Устройства и приборы, разработанные или модифицированные для обслуживания, проверки" />
</part>
</list>
<list num="1030" id="6648" description="Список товаров и технологий двойного назначения, которые могут быть использованы при создании вооружений и военной техники">
<part num="4">
<pos isKey="0" id="6679" pid="6648" description="Раздел 4. Товары и технологии, вывоз которых с территории РФ" />
<pos isKey="0" id="6681" pid="6679" description="Категория 2. Перспективные материалы" />
<pos num="2.2." isKey="0" id="11599" pid="6681" description="Испытательное, контрольное и производственное оборудование" />
<pos num="2.2.1." isKey="1" id="11600" pid="11599" description="Оборудование для тепловых испытаний образцов материалов с углерод-углеродным покрытием" />
例如,对于数字为“9.2.1.2.10”的位置。我在word文档中需要一些输出:
+-------------------------------------------------------------------------------+
| Список оборудования, материалов и технологий, которые могут быть использованы |
| при создании ракетного оружия |
+-------------------------------------------------------------------------------+
| КАТЕГОРИЯ II |
+-------------------------------------------------------------------------------+
| Раздел 9. Измерительное, навигационное и пеленгаторное оборудование и системы |
+-------------------------------------------------------------------------------+
| 9.2. | Испытательное и производственное оборудование |
| 9.2.1. | Производственное, испытательное.. |
| 9.2.1.2. | Испытательное оборудование для инерциальной аппаратуры |
| 9.2.1.2.10.| Установка для осевой регулировки акселерометра |
+-------------------------------------------------------------------------------+
但如果我想要4个位置有“9.2.1.2.10”,“10.2.1”,“2.2.1”,“2.2.2”,我需要一些输出:
+-------------------------------------------------------------------------------+
| Список оборудования, материалов и технологий, которые могут быть использованы |
| при создании ракетного оружия |
+-------------------------------------------------------------------------------+
| КАТЕГОРИЯ II |
+-------------------------------------------------------------------------------+
| Раздел 9. Измерительное, навигационное и пеленгаторное оборудование и системы |
+-------------------------------------------------------------------------------+
| 9.2. | Испытательное и производственное оборудование |
| 9.2.1. | Производственное, испытательное.. |
| 9.2.1.2. | Испытательное оборудование для инерциальной аппаратуры |
| 9.2.1.2.10.| Установка для осевой регулировки акселерометра |
+-------------------------------------------------------------------------------+
| Раздел 10. Системы управления полетом |
+-------------------------------------------------------------------------------+
| 10.2. | Испытательное и производственное оборудование |
| 10.2.1 | Испытательное, калибровочное и регулировочное оборудование |
+-------------------------------------------------------------------------------+
+-------------------------------------------------------------------------------+
| Список товаров и технологий двойного назначения, которые могут быть |
|использованы при создании вооружений и военной техники |
+-------------------------------------------------------------------------------+
| Раздел 4. Товары и технологии, вывоз которых с территории РФ |
+-------------------------------------------------------------------------------+
| Категория 2. Перспективные материалы |
+-------------------------------------------------------------------------------+
| 2.2. | Испытательное, контрольное и производственное оборудование |
| 2.2.1. | Оборудование для тепловых испытаний образцов материалов... |
| 2.2.2. | Оборудование для тепловых испытаний образцов материалов... |
+-------------------------------------------------------------------------------+
到目前为止,我尝试过这样的事情:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Lists</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Id</th>
<th>parentID</th>
</tr>
<xsl:apply-templates select="/goods/good/list/part/pos[@out=1]"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="/goods/good/list/part/pos[@out=1]">
<xsl:variable name="pid" select="./@pid" />
Key node: <span style="color:#ff0000">
<xsl:value-of select="./@num"/><xsl:text>, id = </xsl:text>
<xsl:value-of select="./@id"/><xsl:text>, pid = </xsl:text>
<xsl:value-of select="./@pid"/>
</span><br/>
<xsl:call-template name = "while">
<xsl:with-param name="param" select="$pid"/>
</xsl:call-template>
<br />
</xsl:template>
<xsl:template name = "while">
<xsl:param name="param"/>
<xsl:variable name="pid" select="../pos[@id = $param]/@pid"/>
<tr>
<td><xsl:value-of select="../pos[@id = $param]/@id"/></td>
<td><xsl:value-of select="../pos[@id = $param]/@pid"/></td>
</tr>
Param: <span style="color:#ff0000">
<xsl:value-of select="$param"/>
</span>
Inner var: <span style="color:#ff0000">
<xsl:value-of select="$pid"/>
</span>
<xsl:if test="$pid">
<br/>
<xsl:call-template name = "while">
<xsl:with-param name="param" select="$pid"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
可能有更好的方法来完成这项任务吗?
答案 0 :(得分:2)
在pid
到id
链接链后,您似乎需要为pos
元素设置两个单独的列,这些列具有num
属性和一个两个-column-spanning td
用于其他案例(pos
元素没有num
,或者元素未调用pos
)。您可以使用键跟踪链:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<!-- key to look up any element with an id attribute based on the value of
that id -->
<xsl:key name="elementById" match="*[@id]" use="@id" />
<xsl:template match="/">
<html>
<body>
<h2>Lists</h2>
<xsl:apply-templates select="//*[@out = '1']" mode="table" />
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="table">
<table>
<xsl:apply-templates select="." />
</table>
</xsl:template>
<!-- the main recursive logic - first produce the output for the next
item in the pid->id chain, then produce a row for this element -->
<xsl:template match="*">
<xsl:apply-templates select="key('elementById', @pid)" />
<tr>
<td colspan="2"><xsl:value-of select="@description" /></td>
</tr>
</xsl:template>
<!-- special case for pos elements with a @num - produce two columns -->
<xsl:template match="pos[@num]">
<xsl:apply-templates select="key('elementById', @pid)" />
<tr>
<td><xsl:value-of select="@num" /></td>
<td><xsl:value-of select="@description" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
当我们到达没有pid
属性的元素时,递归会自动停止,因为在这种情况下,键将不匹配任何内容。
如果你想对树中的父链接进行去复制和分组,那么你必须自上而下工作而不是自下而上,反过来链接:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<!-- key to look up any element with an id attribute based on the value of
that id -->
<xsl:key name="elementsByPid" match="*[@pid]" use="@pid" />
<xsl:template match="/">
<html>
<body>
<h2>Lists</h2>
<xsl:apply-templates select="/Good/lists/list" mode="table" />
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="table">
<xsl:variable name="shouldOutput">
<xsl:apply-templates select="." mode="shouldOutput" />
</xsl:variable>
<xsl:if test="string-length($shouldOutput)">
<table>
<xsl:apply-templates select="." />
</table>
</xsl:if>
</xsl:template>
<!-- the main recursive logic - first produce output for this row, then
process any of the children (in the id->pid chain) that need to be
output -->
<xsl:template match="*">
<xsl:apply-templates select="." mode="row" />
<xsl:for-each select="key('elementsByPid', @id)">
<xsl:variable name="shouldOutput">
<xsl:apply-templates select="." mode="shouldOutput" />
</xsl:variable>
<xsl:if test="string-length($shouldOutput)">
<xsl:apply-templates select="." />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="row">
<tr>
<td colspan="2"><xsl:value-of select="@description" /></td>
</tr>
</xsl:template>
<!-- special case for pos elements with a @num - produce two columns -->
<xsl:template match="pos[@num]" mode="row">
<tr>
<td><xsl:value-of select="@num" /></td>
<td><xsl:value-of select="@description" /></td>
</tr>
</xsl:template>
<!-- check whether this node should be output by checking whether it, or any
of its descendants in the id->pid tree, has @out=1. The template will
return an empty RTF for nodes that should not be output, and an RTF
containing a text node with one or more "1" characters for nodes that
should. -->
<xsl:template match="*[@out='1']" mode="shouldOutput">1</xsl:template>
<xsl:template match="*" mode="shouldOutput">
<xsl:apply-templates select="key('elementsByPid', @id)"
mode="shouldOutput"/>
</xsl:template>
</xsl:stylesheet>
对于大型输入文档而言,这将是相当低效的,因为它必须在每个级别跟随整个id-&gt; pid链接到底部,以检查当前节点是否具有 any out="1"
链中的后代。如果您可以预先处理文档以提前计算出这些链,并使用out="1"
标记链中的每个链接,那么逻辑将更加简单和高效。