XSLT:将2个XML文件合并为一个

时间:2017-08-04 11:20:07

标签: xml xslt

我有2个xml文件:

File1中:

<?xml version="1.0" encoding="UTF-8"?>
<offer file_format="IOF" generated="2017-08-04 05:27:56"  version="2.5" extensions="no"><products xmlns:iaiext="http://www.iai-shop.com/developers/iof/extensions.phtml">
    <product id="1356">
        <name>Name1</name>
    </product>
    <product id="1357">
        <name>Name2</name>
    </product>
</products>
</offer>

和File2:

<?xml version="1.0" encoding="UTF-8"?>
<offer file_format="IOF" generated="2017-08-04 05:27:56"  version="2.5" extensions="no">
    <products xmlns:iaiext="http://www.iai-shop.com/developers/iof/extensions.phtml">
        <product id="1356">
            <avail>True</avail>
        </product>
        <product id="1357">
           <avail>False</avail>
        </product>
    </products>
</offer>

我想得到这个:

<product id="1356">
    <name>Name1</name>
    <avail>True</avail>
</product>
<product id="1357">
    <name>Name2</name>
    <avail>False</avail>
</product>

我该怎么做?当我在&#39; name&#39;它读错了&#39;有用&#39;。

我的xslt文件:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSLT/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:for-each select="offer/products/product">
            <xsl:value-of select="name" />
            <xsl:value-of select="document('File2.xml')/offer/products/product/avail"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

我尝试使用变量,结果是一样的。

2 个答案:

答案 0 :(得分:0)

You should be using xsl:copy instead of xsl:value-of of here, as you want to copy the whole node, rather than just the text value.

Additionally, when you select from "file2.xml" you need to specify the current product id in the condition.

Also note, the namespace URI you have shown for the xsl prefix is wrong. It should be "http://www.w3.org/1999/XSL/Transform"

Try this XSLT

<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:template match="/">
        <xsl:for-each select="offer/products/product">
            <xsl:copy>
               <xsl:copy-of select="@*|name" />
               <xsl:copy-of select="document('File2.xml')/offer/products/product[@id = current()/@id]/avail"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

This is an XSLT-1.0 solution also removing the namespace:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:iaiext="http://www.iai-shop.com/developers/iof/extensions.phtml">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:variable name="second" select="document('File2.xml')/offer/products" /> 

    <!-- copy elements without namespace -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <!-- remove offer element -->
    <xsl:template match="offer">
      <xsl:apply-templates />
    </xsl:template>

    <!-- reconstruct 'product' element -->
    <xsl:template match="product">
      <xsl:variable name="id" select="@id" />
      <xsl:element name="product">        <!-- clear the namespace -->
        <name><xsl:value-of select="name" /></name>
        <avail><xsl:value-of select="$second/product[@id=$id]/avail"/></avail>
      </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Output is (with a root element 'products'):

<?xml version="1.0" encoding="UTF-8"?>    
<products>
    <product>
        <name>Name1</name>
        <avail>True</avail>
    </product>
    <product>
        <name>Name2</name>
        <avail>False</avail>
    </product>
</products>
相关问题