问题
I have an xml structure. In xslt template for each position () in each list() I need to find position which attribute @out = 1, then I need to create a tree structure of categories it belongs to using positon's @pid attribute.
<?xml version="1.0" encoding="ISO-8859-1"?>
<Work>
<Goods>
<id="2196">
<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." out = "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." out = "1" isKey="1" id="11600" pid="11599" description="Оборудование для тепловых испытаний образцов материалов с углерод-углеродным покрытием" />
<pos num="2.2.2." out = "1" isKey="1" id="11600" pid="11599" description="Оборудование для тепловых испытаний образцов материалов с углерод-углеродным покрытием" />
</Goods>
<Goods>
<id="2111">
</Goods>
<Goods>
<id="2112">
</Goods>
</Work>
For example if I want 4 positions with nums "9.2.1.2.10", "10.2.1","2.2.1","2.2.2" to be detailed for good with id=2196, I need some output like that:
+-------------------------------------------------------------------------------+
| Список оборудования, материалов и технологий, которые могут быть использованы |
| при создании ракетного оружия |
+-------------------------------------------------------------------------------+
| КАТЕГОРИЯ 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. | Оборудование для тепловых испытаний образцов материалов... |
+-------------------------------------------------------------------------------+
The following code for templates using for forming Word Document gives an error when trying to open a document:
<xsl:template match="ns1:*" mode="table1">
<w:p wsp:rsidR="00785C21" wsp:rsidRPr="00A33D80" wsp:rsidRDefault="00785C21" wsp:rsidP="007E1332">
<w:pPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="EN-US" />
</w:rPr>
<w:t>
<xsl:text>Table output</xsl:text>
</w:t>
</w:r>
</w:p>
<xsl:variable name="shouldOutput">
<xsl:apply-templates select="." mode="shouldOutput" />
</xsl:variable>
<xsl:if test="string-length($shouldOutput)">
<w:tbl>
<w:tblPr>
<w:tblW w:w="0" w:type="auto" />
<w:tblLook w:val="04A0" />
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="222" />
<w:gridCol w:w="222" />
</w:tblGrid>
<w:p wsp:rsidR="00785C21" wsp:rsidRPr="00A33D80" wsp:rsidRDefault="00785C21" wsp:rsidP="007E1332">
<w:pPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="EN-US" />
</w:rPr>
<w:t>
<xsl:text>Table output should output</xsl:text>
</w:t>
</w:r>
</w:p>
<xsl:apply-templates select="." />
</w:tbl>
<!--</table>-->
</xsl:if>
</xsl:template> <!--Matching analysis table-->
<xsl:template match="ns1:*">
<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><!-- 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="ns1:*" mode="row">
<w:tr wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidTr="005C4540">
<w:tc>
<w:tcPr>
<w:tcW w:w="0" w:type="auto" />
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
<w:hmerge w:val="restart"/>
</w:tcPr>
<w:p wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidRDefault="007E1332" wsp:rsidP="005C4540">
<w:pPr>
<w:spacing w:before="20" w:after="20" />
<w:rPr>
<w:rFonts w:cs="Arial" />
</w:rPr>
</w:pPr>
<w:r wsp:rsidRPr="005C4540">
<w:rPr>
<w:rFonts w:ascii="Calibri" w:h-ansi="Calibri" w:cs="Calibri" />
<wx:font wx:val="Calibri" />
<w:b w:val="off" />
<w:color w:val="auto" />
<w:lang w:val="EN-US" />
</w:rPr>
<w:t>
<xsl:value-of select="@description" />
</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="0" w:type="auto" />
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
<w:hmerge w:val ="continue"/>
</w:tcPr>
<w:p wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidRDefault="007E1332" wsp:rsidP="005C4540">
<w:pPr>
<w:spacing w:before="20" w:after="20" />
<w:rPr>
<w:rFonts w:cs="Arial" />
</w:rPr>
</w:pPr>
</w:p>
</w:tc>
</w:tr>
</xsl:template>
<xsl:template match="ns1:pos[@num]" mode="row">
<w:tr wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidTr="005C4540">
<w:tc>
<w:tcPr>
<w:tcW w:w="0" w:type="auto" />
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
</w:tcPr>
<w:p wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidRDefault="007E1332" wsp:rsidP="005C4540">
<w:pPr>
<w:spacing w:before="20" w:after="20" />
<w:rPr>
<w:rFonts w:cs="Arial" />
</w:rPr>
</w:pPr>
<w:r wsp:rsidRPr="005C4540">
<w:rPr>
<w:rFonts w:ascii="Calibri" w:h-ansi="Calibri" w:cs="Calibri" />
<wx:font wx:val="Calibri" />
<w:b w:val="off" />
<w:color w:val="auto" />
<w:lang w:val="EN-US" />
</w:rPr>
<w:t>
<xsl:value-of select="@num" />
</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="0" w:type="auto" />
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
</w:tcPr>
<w:p wsp:rsidR="007E1332" wsp:rsidRPr="005C4540" wsp:rsidRDefault="007E1332" wsp:rsidP="005C4540">
<w:pPr>
<w:spacing w:before="20" w:after="20" />
<w:rPr>
<w:rFonts w:cs="Arial" />
</w:rPr>
</w:pPr>
<w:r wsp:rsidRPr="005C4540">
<w:rPr>
<w:rFonts w:ascii="Calibri" w:h-ansi="Calibri" w:cs="Calibri" />
<wx:font wx:val="Calibri" />
<w:b w:val="off" />
<w:color w:val="auto" />
<w:lang w:val="EN-US" />
</w:rPr>
<w:t>
<xsl:value-of select="@description" />
</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</xsl:template> <!-- special case for pos elements with a @num - produce two columns -->
<xsl:template match="ns1:*[@out='1']" mode="shouldOutput">1</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="ns1:*" mode="shouldOutput">
<xsl:apply-templates select="key('elementsByPid', @id)" mode="shouldOutput"/>
</xsl:template>
At the top of the xsl stylesheet I have a key declaration:
<!-- key to look up any element with an id attribute based on the value of
that id -->
<xsl:key name="elementsByPid" match="ns1:*[@pid]" use="@pid" />
In main template for Goods:
<xsl:template match="/ns1:Work/ns1:Goods">
<ns1:Goods>
<xsl:for-each select="@ns1:*|@*[namespace-uri()='']">
<xsl:attribute name="{name()}" namespace="{namespace-uri()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:for-each>
<!--Here is some WordML code-->
<!--Here I call to one of the above templates to form lists for the current good-->
<xsl:apply-templates select="ns1:list" mode="table" />
</ns1:Goods>
</xsl:template><!--/Goods товары в блоке описания-->
I can't find where is the mistake, but I think I've messed something with match patterns, because for simple html file everything worked fine
来源:https://stackoverflow.com/questions/19378689/messing-xsl-match-patterns-forming-wordml-document