[英]Compare price in two XML files
I don't know what would be the best way to compare price changes in two XML files. 我不知道在两个XML文件中比较价格变化的最佳方法是什么。
With XSLT I generate two (one actual, one older) XML from a price list: 使用XSLT,我可以从价目表中生成两个(一个实际的,一个更旧的)XML:
newer.xml: newer.xml:
<xml>
<produkt>
<code>000161</code>
<name>Test name</name>
<available>Yes</available>
<price>19,90</price>
</produkt>
</xml>
older.xml old.xml
<xml>
<produkt>
<code>000161</code>
<name>Test name</name>
<available>Yes</available>
<price>18,90</price>
</produkt>
</xml>
I tried to do a side by side comparison with a diff tool, but in the second XML are many new products so it's impossible. 我试图与diff工具进行并排比较,但是在第二个XML中有许多新产品,所以这是不可能的。
Perhaps it would be good to generate a new XML with XSLT, but it's beyond my knowledge. 用XSLT生成新的XML也许会很好,但是这超出了我的知识。
<code>
产品由<code>
标识 <code>
does not exist in older.xml
: do not copy) 不要检查或复制新产品( <code>
在older.xml
中不存在:请勿复制) compare.xml compare.xml
<xml>
<produkt>
<code>000161</code>
<name>Test name</name>
<available>Yes</available>
<oldprice>18,90</oldprice>
<newprice>19,90</newprice>
</produkt>
</xml>
older.xml old.xml
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<produkt>
<code>000160</code>
<name>Product A (only in old list)</name>
<available>Yes</available>
<price>9,90</price>
</produkt>
<produkt>
<code>000161</code>
<name>Product B (price falls)</name>
<available>Yes</available>
<price>19,90</price>
</produkt>
<produkt>
<code>000163</code>
<name>Product D (price rises)</name>
<available>Yes</available>
<price>24,90</price>
</produkt>
<produkt>
<code>000164</code>
<name>Product E (price unchanged)</name>
<available>Yes</available>
<price>99,90</price>
</produkt>
</xml>
newer.xml newer.xml
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<produkt>
<code>000161</code>
<name>Product B (price falls)</name>
<available>Yes</available>
<price>18,90</price>
</produkt>
<produkt>
<code>000162</code>
<name>Product C (only in new list)</name>
<available>Yes</available>
<price>16,90</price>
</produkt>
<produkt>
<code>000163</code>
<name>Product D (price rises)</name>
<available>Yes</available>
<price>28,90</price>
</produkt>
<produkt>
<code>000164</code>
<name>Product E (price unchanged)</name>
<available>Yes</available>
<price>99,90</price>
</produkt>
</xml>
compare.xsl compare.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="xml">
<xsl:variable name="older" select="document('older.xml')"/>
<xml>
<xsl:for-each select="produkt">
<xsl:variable name="code" select="code"/>
<xsl:variable name="findProduktByCode" select="$older/xml/produkt[code = $code]"/>
<xsl:if test="price != $findProduktByCode/price">
<produkt>
<xsl:copy-of select="code"/>
<xsl:copy-of select="name"/>
<xsl:copy-of select="available"/>
<oldprice>
<xsl:value-of select="$findProduktByCode/price"/>
</oldprice>
<newprice>
<xsl:value-of select="price"/>
</newprice>
</produkt>
</xsl:if>
</xsl:for-each>
</xml>
</xsl:template>
</xsl:stylesheet>
Now apply compare.xslt on newer.xml: 现在在newer.xml上应用compare.xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<produkt>
<code>000161</code>
<name>Product B (price falls)</name>
<available>Yes</available>
<oldprice>19,90</oldprice>
<newprice>18,90</newprice>
</produkt>
<produkt>
<code>000163</code>
<name>Product D (price rises)</name>
<available>Yes</available>
<oldprice>24,90</oldprice>
<newprice>28,90</newprice>
</produkt>
</xml>
The easy and efficient way to handle cross-references is to use XSLT's built-in key mechanism: 处理交叉引用的一种简单有效的方法是使用XSLT的内置密钥机制:
XSLT 2.0 XSLT 2.0
<xsl:stylesheet version="2.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="*"/>
<xsl:param name="path-to-old" select="'older.xml'"/>
<xsl:key name="product-by-code" match="produkt" use="code" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="produkt">
<xsl:variable name="old-price" select="key('product-by-code', code, document($path-to-old))/price" />
<xsl:if test="$old-price != price">
<xsl:copy>
<xsl:apply-templates select="@*|node() except price"/>
<oldprice>
<xsl:value-of select="$old-price"/>
</oldprice>
<newprice>
<xsl:value-of select="price" />
</newprice>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Applying a key across documents is a bit more complicated in XSLT 1.0, but still possible. 在XSLT 1.0中,跨文档应用密钥比较复杂,但仍然可以实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.