xml - 第一个节点上模板内的数据“数组”的 XSL 模板
问题描述
这是我的 Stackoverflow 帖子 Matching templates with different configuration on the same node的延续,正如我在原始帖子Nesting xsl templates and references multiple templates to the same node?
如何在第一个 ROW 标记上实现模板,这很可能是源 XML 中唯一的 ROW 标记?我的问题涉及 ROW 标记中的最后一个节点,在源 XML 的标记名中包含 E1EDL44:
<?xml version="1.0" encoding="UTF-8"?>
<FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
<ROW>
<EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
<E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
<E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
<E1EDL24.POSNR>000001</E1EDL24.POSNR>
<E1EDL41.QUALI>001</E1EDL41.QUALI>
<E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
<!-- These E1EDL44 lines will appear the same on every ROW, in case there is more than one ROW-->
<!-- There are more tags, actually, left out for simplicity-->
<E1EDL44.VELIN>
<DATA>1</DATA>
<DATA>2</DATA>
<DATA>3</DATA>
</E1EDL44.VELIN>
<E1EDL44.POSNR>
<DATA>000001</DATA>
<DATA>000123</DATA>
<DATA>456789</DATA>
</E1EDL44.POSNR>
</ROW>
<ROW>
<EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
<E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
<E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
<E1EDL24.POSNR>2</E1EDL24.POSNR>
<E1EDL41.QUALI>002</E1EDL41.QUALI>
<E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
<E1EDL44.VELIN>
<DATA>1</DATA>
<DATA>2</DATA>
<DATA>3</DATA>
</E1EDL44.VELIN>
<E1EDL44.POSNR>
<DATA>000001</DATA>
<DATA>000123</DATA>
<DATA>456789</DATA>
</E1EDL44.POSNR>
</ROW>
</FMPDSORESULT>
结果必须是:
<?xml version="1.0" encoding="utf-16"?>
<DELVRY05>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM>EDI_DC40</TABNAM>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN>649758</VBELN>
<E1EDL18 SEGMENT="1">
<QUALF>ORI</QUALF>
</E1EDL18>
<E1EDL24 SEGMENT="1">
<POSNR>000001</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>001</QUALI>
</E1EDL41>
</E1EDL24>
<E1EDL24 SEGMENT="1">
<POSNR>2</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>002</QUALI>
</E1EDL41>
</E1EDL24>
</E1EDL20>
<E1EDL37 SEGMENT="1">
<EXIDV>5650327422</EXIDV>
<E1EDL44 SEGMENT="1">
<VELIN>1</VELIN>
<POSNR>000001</POSNR>
</E1EDL44>
<E1EDL44 SEGMENT="1">
<VELIN>2</VELIN>
<POSNR>000123</POSNR>
</E1EDL44>
<E1EDL44 SEGMENT="1">
<VELIN>3</VELIN>
<POSNR>456789</POSNR>
</E1EDL44>
</E1EDL37>
</IDOC>
</DELVRY05>
在 Sebastien 的帮助下(参见前面提到的帖子),我对 xslt 的看法如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fm="http://www.filemaker.com/fmpdsoresult"
exclude-result-prefixes="fm"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<DELVRY05>
<xsl:apply-templates select="fm:FMPDSORESULT/fm:ROW[1]"/>
</DELVRY05>
</xsl:template>
<xsl:template match="fm:ROW">
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM><xsl:value-of select="fm:EDI_DC40.TABNAM/fm:DATA"/></TABNAM>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN><xsl:value-of select="fm:E1EDL20.VBELN/fm:DATA"/></VBELN>
<E1EDL18 SEGMENT="1"><QUALF><xsl:value-of select="fm:E1EDL18.QUALF/fm:DATA"/></QUALF></E1EDL18>
<!-- Use template for elements that are present mutltiple times. -->
<xsl:apply-templates select="../fm:ROW/fm:E1EDL24.POSNR"/>
<E1EDL37 SEGMENT="1">
<EXIDV><xsl:value-of select="fm:E1EDL37.EXIDV/fm:DATA"/></EXIDV>
<VHILM><xsl:value-of select="fm:E1EDL37.VHILM/fm:DATA"/></VHILM>
<EXIDV2><xsl:value-of select="fm:E1EDL37.EXIDV2/fm:DATA"/></EXIDV2>
<EXIDA><xsl:value-of select="fm:E1EDL37.EXIDA/fm:DATA"/></EXIDA>
<xsl:apply-templates select="fm:E1EDL44.VELIN/fm:DATA"/>
</E1EDL37>
</E1EDL20>
</IDOC>
</xsl:template>
<xsl:template match="fm:E1EDL24.POSNR">
<E1EDL24 SEGMENT="1">
<POSNR><xsl:value-of select="."/></POSNR>
<E1EDL41 SEGMENT="1">
<QUALI><xsl:value-of select="../fm:E1EDL41.QUALI"/></QUALI>
</E1EDL41>
</E1EDL24>
</xsl:template>
<xsl:template match="fm:E1EDL44.VELIN/fm:DATA">
<E1EDL44 SEGMENT="1">
<VELIN><xsl:value-of select="."/></VELIN>
<POSNR><xsl:value-of select="../../fm:E1EDL44.POSNR/fm:DATA"/></POSNR>
</E1EDL44>
</xsl:template>
</xsl:stylesheet>
这适用于 VELIN,但不适用于 POSNR,它总是显示第一个 DATA 标签数据:
<E1EDL37 SEGMENT="1">
<EXIDV>5650327422</EXIDV>
<E1EDL44 SEGMENT="1">
<VELIN>1</VELIN>
<POSNR>000001</POSNR>
</E1EDL44>
<E1EDL44 SEGMENT="1">
<VELIN>1</VELIN>
<POSNR>000001</POSNR>
</E1EDL44>
<E1EDL44 SEGMENT="1">
<VELIN>3</VELIN>
<POSNR>000001</POSNR>
</E1EDL44>
</E1EDL37>
如何修复我的模板?
解决方案
我认为您可以使用<POSNR><xsl:value-of select="../../fm:E1EDL44.POSNR/fm:DATA[position() = current()]"/></POSNR>
. 这假设匹配的元素确实包含 values 1,2,3,4,..
,就像您的示例数据一样。
否则存储
<xsl:variable name="pos" select="position()"/>
并使用<POSNR><xsl:value-of select="../../fm:E1EDL44.POSNR/fm:DATA[$pos]"/></POSNR>
推荐阅读
- mongodb - 查询没有数组的嵌套字段
- java - 如何在休眠中具有一对多或多对一关系的两个表中一一插入数据(每次程序运行)
- firebase - Firestore 操作挂起
- makefile - 如何在 Makefile 中获取父目录
- python - 安装 pip Python
- javascript - 将 PHP 与 Javascript 结合使用以从购物车中删除商品
- javascript - 无法通过 unpkg 使用 MATERIAL-UI & React
- python - 使用 matplotlib 绘制 pandas DataFrame
- css - 为什么 col-sm-12 添加了 col-sm 在引导程序中没有的边距?
- join - EnumerableExtensions.Join 由于其保护级别而无法访问