使用XSLT 3.0,
我输入以下XML:
<?xml ="1.0" encoding="UTF-8"?>
<TABLE NAME="TABLE.DB">
<DATA RECORDS="2">
<RECORD ID="1">
<RECNO>1</RECNO>
<SEQ>0</SEQ>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<ORDER>10355</ORDER>
<CN>PL</CN>
<PROPERTY>06</PROPERTY>
</RECORD>
<RECORD ID="2">
<RECNO>2</RECNO>
<SEQUENCE>0</SEQUENCE>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<ORDER>000026672</ORDER>
<CN>PL 300 L</CN>
</RECORD>
<RECORD ID="3">
<RECNO>3</RECNO>
<SEQUENCE>0</SEQUENCE>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<NUMBER>10357</NUMBER>
<CN>PL 300 L</CN>
<PROPERTY>0</PROPERTY>
</RECORD>
</DATA>
</TABLE>
给定用于匹配的值: (我使用\ t来定义输入文件的制表符分隔性质)
"10355"\t"PL"
"000026672"\t"PL 300 L"
我需要插入所有尚未拥有PROPERTY标记的记录,其值为06
期望的结果:
<?xml ="1.0" encoding="UTF-8"?>
<TABLE NAME="TABLE.DB">
<DATA RECORDS="2">
<RECORD ID="1">
<RECNO>1</RECNO>
<SEQ>0</SEQ>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<ORDER>10355</ORDER>
<CN>PL</CN>
<PROPERTY>06</PROPERTY>
</RECORD>
<RECORD ID="2">
<RECNO>2</RECNO>
<SEQUENCE>0</SEQUENCE>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<ORDER>000026672</ORDER>
<CN>PL 300 L</CN>
<PROPERTY>06</PROPERTY>
</RECORD>
<RECORD ID="3">
<RECNO>3</RECNO>
<SEQUENCE>0</SEQUENCE>
<DATE>17/12/1999 2:44:08 μμ</DATE>
<ID>12/11/2015 3:15:25 μμ</ID>
<NUMBER>10357</NUMBER>
<CN>PL 300 L</CN>
</RECORD>
</DATA>
</TABLE>
我尝试过,添加了element属性,即使它已经存在,所以我最终在同一节点中有两个元素PROPERTY,如果它已经存在的话。你能给我一个示例实现,我使用SAXON最新版本(9.8)
xsl:添加一个元素,即使存在一个元素:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="xsl exsl xs">
<xsl:output method="xml" version="1.0" indent="yes" encoding="utf-8" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="//*[local-name() = 'RECORD ID']">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:choose>
<xsl:when test="not(PRODUCT)">
<PRODUCT><xsl:value-of select="98"/></PRODUCT>
</xsl:when>
<xsl:otherwise>
<xsl:copy><xsl:value-of select="98"/></xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
一直使用我的真实数据建议的解决方案(与示例有很大不同),我面临以下问题:
我怎么能有一个报告让我知道,根据输入文件,哪些添加内容没有插入?
答案 0 :(得分:0)
一些观察结果:
(a)在您的示例输出中,PROPERTY元素已从记录3中删除。我无法在您的要求说明中看到解释原因的任何内容。
(b)在您的要求声明中,句子&#34;我需要插入所有尚未拥有PROPERTY标签的记录,其值为06&#34;很暧昧。我会这样说,如果有一个PROPERTY&#39;标签&#39; (正确的,元素)的值不是06,那么你应该插入另一个PROPERTY元素,但这似乎与你在别处说的相矛盾。
(c)您的代码具有match="//*[local-name() = 'RECORD ID']"
的模板规则。您可以删除&#34; //&#34;在比赛模式开始时,它是多余的。更重要的是,没有元素的本地名称等于&#34;记录ID&#34; - 元素名称不能包含空格。因此,模板规则永远不会匹配任何内容。
(d)假设此模板规则旨在匹配RECORD元素,您当然不希望xsl:copy在xsl中:否则,因为这将创建整个RECORD的嵌套副本。
(e)您已经要求提供XSLT 3.0解决方案,但您的问题中没有任何内容需要XSLT 3.0,事实上您自己的样式表说版本=&#34; 2.0&#34;
(f)我无法看到制表符分隔的参数文件在其中扮演的角色。
简而言之,在任何人开始编写任何代码之前,需要进行大量的澄清。
答案 1 :(得分:0)
您的解决方案需要进行一些更改:
模板与RECORD
匹配,而不是RECORD ID
(ID
是
属性,不参与任何决定。)
您的一般概念还可以:
<RECORD>
),RECORD
,PROPERTY
(不是PRODUCT
)元素是否缺席(在
当前RECORD
),PROPERTY
元素</RECORD>
)。我删除了otherwise
部分(不需要)并将choose
更改为
一个if
..
在指定 XSLT 3.0 时,即使身份模板也可以
替换为(稍短)on-no-match="shallow-copy"
。
我还在您的源XML中添加了version
。否则它的格式不正确。
所以整个脚本可能如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="RECORD">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:if test="not(PROPERTY)">
<PROPERTY>06</PROPERTY>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
上进行测试