向节点添加元素(如果它不存在)

时间:2017-09-26 07:12:59

标签: xml xslt-2.0 xslt-3.0

使用xslt-3,

我尝试插入元素PROPERTY,如果它尚不存在于每个RECORD节点:

<?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>
            </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>10356</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>

期望的结果:

  <?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>10356</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>
                <PROPERTY>0</PROPERTY>
            </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>

2 个答案:

答案 0 :(得分:2)

可以使用xsl:mode编写身份转换,然后您只需添加一个匹配RECORD[not(PROPERTY)]/*[last()]的模板(RECORD的最后一个子元素,而不是PROPERTY)复制最后一个孩子并添加新的PROPERTY

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:param name="new-prop" as="element(PROPERTY)"><PROPERTY>98</PROPERTY></xsl:param>

    <xsl:template match="RECORD[not(PROPERTY)]/*[last()]">
        <xsl:copy-of select="., $new-prop"/>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

另一种方法是

<xsl:param name="new-prop" as="element(PROPERTY)">
  <PROPERTY>98</PROPERTY>
</xsl:param>

<xsl:template match="RECORD">
  <RECORD ID="{@ID}">
    <xsl:copy-of select="* except PROPERTY, (PROPERTY, $new-prop)[1]"/>
  </RECORD>
</xsl:template>