我公司使用hadoop处理很多产品Feed。我们有一个过程来提取一个产品节点,并在文件中创建一行。然后我们使用xsl将产品xml转换为单行三重管道分隔文件。到目前为止,这一点运作良好。但是我遇到了一个客户端的问题。 他们在新的xml文件中做了一些更改,使用了一些命名空间,这导致了事情的破坏。 我不得不修改xml中的链接,所以我可以发布它。我把http更改为httc 原始xml文件设置如下:
<?xml version="1.0" encoding="utf-8"?>
<CATALOG APIKEY="88ac00e4f3e16e44" xmlns="urn:rrXML" xmlns:xsd="httc://www.w3.org/2001/XMLSchema" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">
<PRODUCTS>
<PRODUCT ID="692174">
<PRODUCTNAME>HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</PRODUCTNAME>
<PRODUCTDESCRIPTION></PRODUCTDESCRIPTION>
<PRODUCTSKU>100005487</PRODUCTSKU>
<LISTPRICE>$499.99</LISTPRICE>
<SALEPRICE xsi:type="xsd:string" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">$499.99</SALEPRICE>
<PRODUCTURL>/.product.100005487.html</PRODUCTURL>
<IMAGEURL>httc://images.test-static.com/image/media/150-__1</IMAGEURL>
<RATING xsi:type="xsd:string" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">0.0</RATING>
<BRAND>HEWLETT PACKARD</BRAND>
<INSTOCK>1</INSTOCK>
<REVIEWS xsi:type="xsd:string" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">0</REVIEWS>
<KEYWORDS></KEYWORDS>
<ACTIONBUTTONURL></ACTIONBUTTONURL>
<PARENTPRODUCTID>100005487</PARENTPRODUCTID>
<CATEGORIES />
<ATTRIBUTES>
<ATTRIBUTE NAME="Categories">Kaspersky Promotion</ATTRIBUTE>
<ATTRIBUTE NAME="FSA">False</ATTRIBUTE>
<ATTRIBUTE NAME="HIDEPRICEFROMBROWSE">False</ATTRIBUTE>
<ATTRIBUTE NAME="ADDTOCARTFROMSEARCH">0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMINQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMAXQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="MERCHANDISINGDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="DISCOUNTDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="ALTTEXT">HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</ATTRIBUTE>
<ATTRIBUTE NAME="MAPITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="MEMBERONLYITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="Brand">HP</ATTRIBUTE>
<ATTRIBUTE NAME="Graphic Card">Intel HD Graphics</ATTRIBUTE>
<ATTRIBUTE NAME="Hard Drive Size">500 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Operating System">Windows ®</ATTRIBUTE>
<ATTRIBUTE NAME="RAM Included">4 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Screen Size">15.6 in.</ATTRIBUTE>
</ATTRIBUTES>
</PRODUCT>
新的xml文件设置如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CATALOG APIKEY="88ac00e4f3e16e44" xmlns="urn:rrXML" xmlns:xsd="httc://www.w3.org/2001/XMLSchema" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">
<PRODUCTS>
<PRODUCT ID="692174">
<PRODUCTNAME>HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</PRODUCTNAME>
<PRODUCTDESCRIPTION></PRODUCTDESCRIPTION>
<PRODUCTSKU>100005487</PRODUCTSKU>
<LISTPRICE>$499.99</LISTPRICE>
<SALEPRICE xsi:type="xsd:string">$499.99</SALEPRICE>
<PRODUCTURL>/.product.100005487.html</PRODUCTURL>
<IMAGEURL>httc://images.test-static.com/image/media/150-__1</IMAGEURL>
<RATING xsi:type="xsd:string">0.0</RATING>
<BRAND>HEWLETT PACKARD</BRAND>
<INSTOCK>1</INSTOCK>
<REVIEWS xsi:type="xsd:string">0</REVIEWS>
<KEYWORDS></KEYWORDS>
<ACTIONBUTTONURL></ACTIONBUTTONURL>
<PARENTPRODUCTID>100005487</PARENTPRODUCTID>
<CATEGORIES>
<CATEGORY ID="103510">
<CATEGORYNAME>Kaspersky Promotion</CATEGORYNAME>
</CATEGORY>
</CATEGORIES>
<ATTRIBUTES>
<ATTRIBUTE NAME="Categories">Kaspersky Promotion</ATTRIBUTE>
<ATTRIBUTE NAME="FSA">False</ATTRIBUTE>
<ATTRIBUTE NAME="HIDEPRICEFROMBROWSE">False</ATTRIBUTE>
<ATTRIBUTE NAME="ADDTOCARTFROMSEARCH">0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMINQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMAXQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="MERCHANDISINGDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="DISCOUNTDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="ALTTEXT">HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</ATTRIBUTE>
<ATTRIBUTE NAME="MAPITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="MEMBERONLYITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="Brand">HP</ATTRIBUTE>
<ATTRIBUTE NAME="Graphic Card">Intel HD Graphics</ATTRIBUTE>
<ATTRIBUTE NAME="Hard Drive Size">500 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Operating System">Windows ®</ATTRIBUTE>
<ATTRIBUTE NAME="RAM Included">4 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Screen Size">15.6 in.</ATTRIBUTE>
</ATTRIBUTES>
</PRODUCT>
将产品转换为单行时,我们只接收产品开头和结束标记之间的所有内容。
当我们使用新文件执行此操作时,它失败了,因为它正在从命名空间中删除。所以我修改了这个过程,在产品中包含了一个带有命名空间标签的包装器。因此,通过xsl发送的文本是:
<wrapper xmlns="urn:rrXML" xmlns:xsd="httc://www.w3.org/2001/XMLSchema" xmlns:xsi="httc://www.w3.org/2001/XMLSchema-instance">
<PRODUCTS>
<PRODUCT ID="692174">
<PRODUCTNAME>HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</PRODUCTNAME>
<PRODUCTDESCRIPTION></PRODUCTDESCRIPTION>
<PRODUCTSKU>100005487</PRODUCTSKU>
<LISTPRICE>$499.99</LISTPRICE>
<SALEPRICE xsi:type="xsd:string">$499.99</SALEPRICE>
<PRODUCTURL>/.product.100005487.html</PRODUCTURL>
<IMAGEURL>httc://images.test-static.com/image/media/150-__1</IMAGEURL>
<RATING xsi:type="xsd:string">0.0</RATING>
<BRAND>HEWLETT PACKARD</BRAND>
<INSTOCK>1</INSTOCK>
<REVIEWS xsi:type="xsd:string">0</REVIEWS>
<KEYWORDS></KEYWORDS>
<ACTIONBUTTONURL></ACTIONBUTTONURL>
<PARENTPRODUCTID>100005487</PARENTPRODUCTID>
<CATEGORIES>
<CATEGORY ID="103510">
<CATEGORYNAME>Kaspersky Promotion</CATEGORYNAME>
</CATEGORY>
</CATEGORIES>
<ATTRIBUTES>
<ATTRIBUTE NAME="Categories">Kaspersky Promotion</ATTRIBUTE>
<ATTRIBUTE NAME="FSA">False</ATTRIBUTE>
<ATTRIBUTE NAME="HIDEPRICEFROMBROWSE">False</ATTRIBUTE>
<ATTRIBUTE NAME="ADDTOCARTFROMSEARCH">0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMINQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="ITEMMAXQTY">1.0</ATTRIBUTE>
<ATTRIBUTE NAME="MERCHANDISINGDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="DISCOUNTDESC"></ATTRIBUTE>
<ATTRIBUTE NAME="ALTTEXT">HP Pavilion g6t Laptop 3rd generation Intel® Core™ i5-3210M 2.5GHz SuperMulti 8X DVD+/-R/RW</ATTRIBUTE>
<ATTRIBUTE NAME="MAPITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="MEMBERONLYITEM">False</ATTRIBUTE>
<ATTRIBUTE NAME="Brand">HP</ATTRIBUTE>
<ATTRIBUTE NAME="Graphic Card">Intel HD Graphics</ATTRIBUTE>
<ATTRIBUTE NAME="Hard Drive Size">500 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Operating System">Windows ®</ATTRIBUTE>
<ATTRIBUTE NAME="RAM Included">4 GB</ATTRIBUTE>
<ATTRIBUTE NAME="Screen Size">15.6 in.</ATTRIBUTE>
</ATTRIBUTES>
</PRODUCT>
</wrapper>
我尝试使用的xsl是:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="httc://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="PRODUCT">
<!-- skuId --><xsl:value-of select="PRODUCTSKU"/>
<xsl:text>|||</xsl:text>
<!-- parentSkuId --><xsl:value-of select="PARENTPRODUCTID"/>
<xsl:text>|||</xsl:text>
<!-- globalSkuID --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- TaxonomyKey Path --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- TaxonomyText --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- upc --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- mpn --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- model_Number --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- Name --><xsl:value-of select="PRODUCTNAME"/>
<xsl:text>|||</xsl:text>
<!-- shortDescription --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- longDescription --><xsl:value-of select="PRODUCTDESCRIPTION"/>
<xsl:text>|||</xsl:text>
<!-- price --><xsl:value-of select="SALEPRICE"/>
<xsl:text>|||</xsl:text>
<!-- comparePrice --><xsl:value-of select="LISTPRICE"/>
<xsl:text>|||</xsl:text>
<!-- productPage --><xsl:value-of select="PRODUCTURL"/>
<xsl:text>|||</xsl:text>
<!-- thumbnail --><xsl:value-of select="IMAGEURL"/>
<xsl:text>|||</xsl:text>
<!-- fullImage --><xsl:value-of select="IMAGEURL"/>
<xsl:text>|||</xsl:text>
<!-- rating --><xsl:value-of select="RATING"/>
<xsl:text>|||</xsl:text>
<!-- brand --><xsl:value-of select="BRAND"/>
<xsl:text>|||</xsl:text>
<!-- isActive --><xsl:value-of select="INSTOCK"/>
<xsl:text>|||</xsl:text>
<!-- ReviewCouunt --><xsl:value-of select="REVIEWS"/>
<xsl:text>|||</xsl:text>
<!-- AlternateTaxonomyKeys -->
<xsl:for-each select="CATEGORIES/CATEGORY">
<xsl:value-of select="@ID" /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- AlternateTaxonomyNames -->
<xsl:for-each select="CATEGORIES/CATEGORY/CATEGORYNAME">
<xsl:value-of select="." /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- AttributeNames -->
<xsl:for-each select="ATTRIBUTES/ATTRIBUTE">
<xsl:value-of select="@NAME" /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- Attribute Values -->
<xsl:for-each select="ATTRIBUTES/ATTRIBUTE">
<xsl:value-of select="." /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
这导致只输出从产品级节点连接的字符串,如: HP Pavilion g6t笔记本电脑第3代Intel®Core™i5-3210M 2.5GHz SuperMulti 8X DVD +/- R / RW100005487 $ 499.99 $ 499.99 / .product.100005487.htmlhttc://images.test-static.com/image/media/150-__10 .0HEWLETT PACKARD10100005487
我猜它与它们所包含的命名空间有关但我对使用xsl找出什么并不是很了解。 请帮忙
答案 0 :(得分:1)
您必须通过定义具有相同namespace-uri()
的命名空间来将XML文档的命名空间添加到XSLT,例如xmlns:u="urn:rrXML"
。然后,您可以使用此前缀访问XML中的元素,这意味着:您使用<xsl:value-of select="u:PRODUCTSKU"/>
而不是<xsl:value-of select="PRODUCTSKU"/>
获取值。在输入XML中添加缺少的结束PRODUCTS标记时,遵循XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:u="urn:rrXML"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="u:PRODUCT" >
<!-- skuId --><xsl:value-of select="u:PRODUCTSKU"/>
<xsl:text>|||</xsl:text>
<!-- parentSkuId --><xsl:value-of select="u:PARENTPRODUCTID"/>
<xsl:text>|||</xsl:text>
<!-- globalSkuID --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- TaxonomyKey Path --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- TaxonomyText --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- upc --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- mpn --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- model_Number --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- Name --><xsl:value-of select="u:PRODUCTNAME"/>
<xsl:text>|||</xsl:text>
<!-- shortDescription --><xsl:text></xsl:text>
<xsl:text>|||</xsl:text>
<!-- longDescription --><xsl:value-of select="u:PRODUCTDESCRIPTION"/>
<xsl:text>|||</xsl:text>
<!-- price --><xsl:value-of select="u:SALEPRICE" />
<xsl:text>|||</xsl:text>
<!-- comparePrice --><xsl:value-of select="u:LISTPRICE"/>
<xsl:text>|||</xsl:text>
<!-- productPage --><xsl:value-of select="u:PRODUCTURL"/>
<xsl:text>|||</xsl:text>
<!-- thumbnail --><xsl:value-of select="u:IMAGEURL"/>
<xsl:text>|||</xsl:text>
<!-- fullImage --><xsl:value-of select="u:IMAGEURL"/>
<xsl:text>|||</xsl:text>
<!-- rating --><xsl:value-of select="u:RATING"/>
<xsl:text>|||</xsl:text>
<!-- brand --><xsl:value-of select="u:BRAND"/>
<xsl:text>|||</xsl:text>
<!-- isActive --><xsl:value-of select="u:INSTOCK"/>
<xsl:text>|||</xsl:text>
<!-- ReviewCouunt --><xsl:value-of select="u:REVIEWS"/>
<xsl:text>|||</xsl:text>
<!-- AlternateTaxonomyKeys -->
<xsl:for-each select="u:CATEGORIES/u:CATEGORY">
<xsl:value-of select="@ID" /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- AlternateTaxonomyNames -->
<xsl:for-each select="u:CATEGORIES/u:CATEGORY/u:CATEGORYNAME">
<xsl:value-of select="." /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- AttributeNames -->
<xsl:for-each select="u:ATTRIBUTES/u:ATTRIBUTE">
<xsl:value-of select="@NAME" /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>|||</xsl:text>
<!-- Attribute Values -->
<xsl:for-each select="u:ATTRIBUTES/u:ATTRIBUTE">
<xsl:value-of select="." /><xsl:text>^</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
产生输出
100005487 ||| 100005487 ||||||||||||||||||||| HP Pavilion g6t笔记本电脑第3代Intel®Core™i5-3210M 2.5GHz SuperMulti 8X DVD +/- R / RW | |||||||| $ 499.99 ||| $ 499.99 ||| /.product.100005487.html ||| httc://images.test-static.com/image/media/150-__1 ||| httc: //images.test-static.com/image/media/150-__1|||0.0||| HEWLETT PACKARD ||| 1 ||| 0 ||| 103510 ^ |||卡巴斯基促销^ |||类别^ FSA ^ HIDEPRICEFROMBROWSE ^ ADDTOCARTFROMSEARCH ^ ITEMMINQTY ^ ITEMMAXQTY ^ MERCHANDISINGDESC ^ DISCOUNTDESC ^ ALTTEXT ^ MAPITEM ^ MEMBERONLYITEM ^ Brand ^图形卡^硬盘尺寸^操作系统^ RAM包括^屏幕尺寸^ |||卡巴斯基促销^错误^错误^ 0 ^ 1.0 ^ 1.0 ^^^ HP Pavilion g6t笔记本电脑第3代Intel®Core™i5-3210M 2.5GHz SuperMulti 8X DVD +/- R / RW ^ False ^ False ^ HP ^ Intel HD Graphics ^ 500 GB ^Windows®^ 4 GB ^ 15.6英寸^
在一行中,如果这确实是预期的输出。
答案 1 :(得分:0)
我猜它与它们的名称空间有关 包括但我不太了解使用xsl来搞清楚 什么。
您正在猜测 - 并且短搜索应该已经揭示了答案:为命名空间分配前缀并在寻址XML源的元素时使用该前缀,例如:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rrx="urn:rrXML">
<xsl:strip-space elements="*" />
<xsl:output method="text"/>
<xsl:template match="rrx:PRODUCT">
<!-- skuId --><xsl:value-of select="rrx:PRODUCTSKU"/>
<xsl:text>|||</xsl:text>
<!-- parentSkuId --><xsl:value-of select="rrx:PARENTPRODUCTID"/>
<xsl:text>|||</xsl:text>
<!-- etc. -->
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>