xml - XSLT - 在 for-each 中更改 XPATH
问题描述
我在这里的第一条消息,我希望我能做对!欢迎任何帮助或建设性帮助(我是初学者)!我有一个产品可以有 2 个不同的名称 + 一些其他属性。我想为每个可能的主要名称和次要名称排上一排。
我调用了一个模板来显示主要名称,另一个调用产品的属性,没有问题,因为节点处于相同的“级别”。
然后我想调用第二个模板在同一行显示每个产品可能的每个第二个名称,然后调用属性模板,问题是我不能在“for-each”函数中回到父节点一次.
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="SOF.xsl" ?>
<root>
<intrants>
<CCCs>
<PPP>
<nbID>01</nbID>
<product-name>MainNameA</product-name>
<int-composition>
<act-subs>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000001">subA</substance>
<variant>
<name>substanceA</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="g/L">123.0</AS-concentration>
</act-sub>
</act-subs>
</int-composition>
</PPP>
<PPP>
<nbID>02</nbID>
<product-name>MainNameB</product-name>
<others-names> </others-names>
<int-composition>
<act-subs>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000001">subA</substance>
<variant>
<name>substanceA</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="g/L">123.0</AS-concentration>
</act-sub>
</act-subs>
</int-composition>
</PPP>
<PPP>
<nbID>03</nbID>
<product-name>MainNameC</product-name>
<others-names>
<other-name>
<type-name ref-type="type-name" ref-id="20150522093431975033" lib-court="SEC">Second name</type-name>
<name>SecondNameC</name>
</other-name>
</others-names>
<int-composition>
<act-subs>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000001">subA</substance>
<variant>
<name>substanceA</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="g/L">123.0</AS-concentration>
</act-sub>
</act-subs>
</int-composition>
</PPP>
<PPP>
<nbID>04</nbID>
<product-name>MainNameD</product-name>
<others-names>
<other-name>
<type-name ref-type="type-name" ref-id="20150522093431975033" lib-court="SEC">Second name</type-name>
<name>SecondName1D</name>
</other-name>
<other-name>
<type-name ref-type="type-name" ref-id="20150522093431975033" lib-court="SEC">Second name</type-name>
<name>SecondName2D</name>
</other-name>
</others-names>
<int-composition>
<act-subs>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000001">subA</substance>
<variant>
<name>substanceA</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="g/L">123.0</AS-concentration>
</act-sub>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000002">subB</substance>
<variant>
<name>substanceB</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="g/kg">456.0</AS-concentration>
</act-sub>
<act-sub>
<substance ref-type="substance" ref-id="00000000000000000003">subC</substance>
<variant>
<name>substanceC</name>
</variant>
<AS-concentration unite-id="10000000000000000001" unite="%/L">678.0</AS-concentration>
</act-sub>
</act-subs>
</int-composition>
</PPP>
</CCCs>
</intrants>
</root>
XLM:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>Rep</title>
</head>
<body>
<table style="width:100%">
<tr>
<th>Name</th>
<th>ID</th>
<th>Composition</th>
</tr>
<xsl:for-each select="root/intrants/CCCs/PPP">
<tr>
<xsl:call-template name="displayMN">
<xsl:with-param name="MN" select="." />
</xsl:call-template>
</tr>
</xsl:for-each>
<xsl:for-each select="/root/intrants/CCCs/PPP">
<xsl:if test="count(others-names/other-name) > 0">
<xsl:for-each select="others-names/other-name/name">
<tr>
<xsl:call-template name="displaySN">
<xsl:with-param name="SN" select="/root/intrants/CCCs/PPP"/>
</xsl:call-template>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<!-- Main Product -->
<xsl:template name="displayMN">
<xsl:param name="MN"/>
<td>
<xsl:call-template name="displayMainName">
<xsl:with-param name="name" select="product-name"/>
</xsl:call-template>
</td>
<xsl:call-template name="displayCore">
<xsl:with-param name="Produit" select="."/>
</xsl:call-template>
</xsl:template>
<!-- Second Product -->
<xsl:template name="displaySN">
<xsl:param name="SN"/>
<td>
<xsl:call-template name="displaySecondName">
<xsl:with-param name="name" select="."/>
</xsl:call-template>
</td>
<xsl:call-template name="displayCore">
<xsl:with-param name="Produit" select="."/>
</xsl:call-template>
</xsl:template>
<!-- Core -->
<xsl:template name="displayCore">
<xsl:param name="Produit"/>
<td>
<xsl:call-template name="displaynbID">
<xsl:with-param name="nbID" select="nbID"/>
</xsl:call-template>
</td>
<td>
<xsl:call-template name="displayCompositionEN">
<xsl:with-param name="Composition" select="."/>
</xsl:call-template>
</td>
</xsl:template>
<!-- Main Name -->
<xsl:template name="displayMainName">
<xsl:param name="name"/>
<xsl:value-of select="$name"/>
</xsl:template>
<!-- Second Name -->
<xsl:template name="displaySecondName">
<xsl:param name="name"/>
<xsl:value-of select="$name"/>
</xsl:template>
<!-- IDnb -->
<xsl:template name="displaynbID">
<xsl:param name="nbID"/>
<xsl:value-of select="$nbID"/>
</xsl:template>
<!-- Composition EN -->
<xsl:template name="displayCompositionEN">
<xsl:param name="Composition"/>
<xsl:for-each select="int-composition/act-subs/act-sub">
<xsl:call-template name="displaySubstanceEN">
<xsl:with-param name="AS" select="substance"/>
<xsl:with-param name="SACc" select="AS-concentration"/>
</xsl:call-template>
<xsl:if test="position() != last()">
<xsl:text> + </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Substance EN-->
<xsl:template name="displaySubstanceEN">
<xsl:param name="AS"/>
<xsl:param name="SACc"/>
<xsl:value-of select="$AS"/> <xsl:value-of select="$SACc"/> <xsl:value-of select="$SACc/@unite"/>
</xsl:template>
</xsl:stylesheet>
正如您在生成的转换中看到的那样,我无法返回属性信息:
解决方案
我假设例如在包含SecondNameC的行中,在其余列中应该显示与MainNameC相同的值,即03
和
subA 123.0 g/L
。
下面的脚本完成了这项工作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.1//EN"
doctype-system= "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>
<xsl:template match="/">
<html>
<head><title>Rep</title></head>
<body>
<table style="width:80%" border="1">
<tr><th>Name</th><th>ID</th><th>Composition</th></tr>
<xsl:for-each select="root/intrants/CCCs/PPP">
<tr>
<xsl:call-template name="displayMN">
<xsl:with-param name="MN" select="." />
</xsl:call-template>
</tr>
</xsl:for-each>
<xsl:for-each select="root/intrants/CCCs/PPP">
<xsl:variable name="MN" select="."/>
<xsl:if test="count(others-names/other-name) > 0">
<xsl:for-each select="others-names/other-name/name">
<tr>
<xsl:call-template name="displaySN">
<xsl:with-param name="MN" select="$MN"/>
</xsl:call-template>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<!-- Main Product -->
<xsl:template name="displayMN">
<xsl:param name="MN"/>
<td>
<xsl:call-template name="displayMainName">
<xsl:with-param name="name" select="product-name"/>
</xsl:call-template>
</td>
<xsl:call-template name="displayCore">
<xsl:with-param name="Produit" select="."/>
</xsl:call-template>
</xsl:template>
<!-- Second Product -->
<xsl:template name="displaySN">
<xsl:param name="MN"/>
<td>
<xsl:call-template name="displaySecondName">
<xsl:with-param name="name" select="."/>
</xsl:call-template>
</td>
<xsl:call-template name="displayCore">
<xsl:with-param name="Produit" select="$MN"/>
</xsl:call-template>
</xsl:template>
<!-- Core -->
<xsl:template name="displayCore">
<xsl:param name="Produit"/>
<td>
<xsl:call-template name="displaynbID">
<xsl:with-param name="nbID" select="$Produit/nbID"/>
</xsl:call-template>
</td>
<td>
<xsl:call-template name="displayCompositionEN">
<xsl:with-param name="Composition" select="$Produit"/>
</xsl:call-template>
</td>
</xsl:template>
<!-- Main Name -->
<xsl:template name="displayMainName">
<xsl:param name="name"/>
<xsl:value-of select="$name"/>
</xsl:template>
<!-- Second Name -->
<xsl:template name="displaySecondName">
<xsl:param name="name"/>
<xsl:value-of select="$name"/>
</xsl:template>
<!-- IDnb -->
<xsl:template name="displaynbID">
<xsl:param name="nbID"/>
<xsl:value-of select="$nbID"/>
</xsl:template>
<!-- Composition EN -->
<xsl:template name="displayCompositionEN">
<xsl:param name="Composition"/>
<xsl:for-each select="$Composition/int-composition/act-subs/act-sub">
<xsl:call-template name="displaySubstanceEN">
<xsl:with-param name="AS" select="substance"/>
<xsl:with-param name="SACc" select="AS-concentration"/>
</xsl:call-template>
<xsl:if test="position() != last()">
<xsl:text> + </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Substance EN-->
<xsl:template name="displaySubstanceEN">
<xsl:param name="AS"/>
<xsl:param name="SACc"/>
<xsl:value-of select="$AS"/> <xsl:value-of select="$SACc"/> <xsl:value-of select="$SACc/@unite"/>
</xsl:template>
</xsl:stylesheet>
有关工作示例,请参见http://xsltransform.net/asnmyT
我看到您忘记了上下文项已更改,例如在for-each
循环中。
另请注意,我更改了displaySN模板。它包含MN
参数,指的是“main”(PPP)元素。
displayCompositionEN模板也有一些变化。
我还添加了带有和属性的xsl:output
元素
来生成 XHTML 输出,以便在
xsltransform测试站点中获取 HTML 视图。但是,如果您不需要它,只需将其删除。doctype-public
doctype-system
推荐阅读
- python - 运行 pytest 时,more-itertools 中的语法无效
- amazon-web-services - 是否有适用于 micronaut 应用程序的 AWS 处理程序?
- javascript - NodeJS IO 饿死但定时器仍在运行?
- android - 是否可以在 Chrome 自定义选项卡上隐藏 URL 栏
- ruby-on-rails - 如何将语言环境传递给 Minitest 集成测试
- c++ - QTCharts“cartesianchartaxis_p.h”处的 QT nmake 异常“未定义接口”
- ios - 预览视图控制器时contanerview颜色不会改变
- mysql - 将 .sql 文件导入 cassandra
- javascript - 如何修复来自 Google Drive API 的“资源正文包含不可直接写入的字段”警告?
- java - 在 JPQL 中将表修剪为 500 条记录