使用XSLT的XML到XML:如何检查输出xml中是否存在该元素,如果不是创建具有默认值的元素

时间:2015-06-09 16:09:23

标签: xml xslt

新手在这里使用XSLT。我正在从另一个XML创建一个XML。每个XML都遵循不同的XSD,但非常相似。我一直在给出最终输出xml中必需元素的列表。所以我有所有必需元素的xpath。我的问题是如何确保所需的元素存在,如果不存在,我将在输出xml文件中生成所需的元素。

所以我的方法是:源XML和输出XML(目标XML)将非常相似,几乎没有差异(XSD是90%相同)我首先使用身份转换模板复制整个xml。然后我需要检查所需的元素,以确保它们出现在结果树中。

例如:

鉴于此XML:

<?xml version="1.0" encoding="UTF-8"?>
<orders>
    <order>
        <order_id>555435699</order_id>
        <products>
            <product>Book1</product>
            <product>Book2</product>
        </products>
        <customer>
            <name>Mike Smith</name>
            <address>1222 N 1st St, Chicago IL</address>
        </customer>
    </order>
</orders>

OUTPUT应该是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<orders>
    <order>
        <order_id>555435699</order_id>
        <products>
            <product>Book1</product>
            <product>Book2</product>
        </products>
        <customer>
            <name>Mike Smith</name>
            <address>1222 N 1st St, Chicago IL</address>
                     <phone>555-555-5555</phone> <!-- Required element 'phone' needs to be populated with default value in output if it doesn't exist -->
        </customer>
    </order>
</orders>

需要确保客户电话数据存在或需要使用默认值'555-555-5555

创建
<xsl:if test="not(node_xpath)">
    <!-- need to add the element -->
</xsl:if>

我们如何使用诸如“if”和“test”来检查xslt。我已经看到这些和那里使用过的。这些是自己单独的模板,还是需要包含在内。这应该如何应用于上述示例?

更新:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<!-- copy entire xml from source xml file -->
<xsl:template match="@*|node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
   </xsl:copy>   
</xsl:template>

<!-- need to check for required tags -  - HOW TO INTEGRATE THIS PART -->
<xsl:if test="not(orders/order/customer/phone)">
    <phone>555-555-5555</phone>
</xsl:if>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

只需添加一个与没有客户的订单匹配的模板,并让它将默认客户写入结果:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="order[not(customer)]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <customer>
            <phone>555-555-5555</phone>
        </customer>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  

我认为开始时我并不太清楚。让我们说我需要确定   每个客户都有一个<phone>元素数据。如果没有,那么我需要   使用默认值在xml outpu中填充它。

然后匹配没有电话的客户:

<xsl:template match="customer[not(phone)]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <phone>555-555-5555</phone>
    </xsl:copy>
</xsl:template>

答案 1 :(得分:-1)

我会为每个必需的输出节点创建一个template。如果要复制的现有输入节点,您希望模板匹配。您可以将缺失数据的默认结果插入模板中。

xsl相当复杂但非常强大。您需要阅读文档才能理解它。