Java 通过XSLT将异常XML数据转换为CSV
多谢各位Java 通过XSLT将异常XML数据转换为CSV,java,xml,csv,xslt,text-files,Java,Xml,Csv,Xslt,Text Files,多谢各位 此XSLT将提供您指定的输出。看 更新:我在输出中遗漏了a值 Name,a,b,c,d,e,f House01,40000,100000,160000,150000,190000,350000 姓名,a,b,c,d,e,f , , , , , , 第二个(最终).csv可以按如下方式生成: XSLT1.0 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="
此XSLT将提供您指定的输出。看 更新:我在输出中遗漏了
a
值
Name,a,b,c,d,e,f
House01,40000,100000,160000,150000,190000,350000
姓名,a,b,c,d,e,f
,
,
,
,
,
,
第二个(最终).csv可以按如下方式生成:
XSLT1.0
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:text>Name,a,b,c,d,e,f
</xsl:text>
<xsl:apply-templates select="FirstTag/SecondTag/a/Furniture"/>
</xsl:template>
<xsl:template match="Furniture">
<xsl:variable name="pos" select="position()"/>
<xsl:value-of select="../../@Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../b/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../c/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../d/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../e/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../f/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
名称
,
,
,
这假设您仅限于XSLT1.0;在XSLT2.0中,这可以在一次传递中完成
请注意,我假设输入XML将包含一个单个“house”(SecondTag
),其中包含数量可变的“rooms”(a
,b
,c
,等等)。否则就不清楚.csv的标题应该是什么
我不确定是否还需要临时.csv,而且在任何情况下,创建它所需的逻辑都不清楚(为什么输出中缺少
FUR00013
)。家具节点是否会在没有最小或最大限制的房间中变化?是的。但是每个房间只有1个数据,这是每个家具价格的总和。例如,一个房间有4件家具,csv中的输出将是这4件家具的总数。您的底部结果总和甚至比原始结果更简单。顶部的逗号分隔值是多少?等等,为什么加起来是40000而不是30000,接下来是70000,接下来是110000?@Parfait加起来(@FURN\u AMT*@price)
,即a=2*10000+1*20000=40000
。f
的结果是590000
,而不是350000
。如果家具f有两件以上的家具,如何获取f房间中所有家具的总价?刚刚意识到输出xml每个房间只有2件家具,如果一个房间中有2件以上的家具,则不会包含在循环中,请参阅Edited您现在期望的输出是什么?3个单独的行,其中第3行有空白字段?还是一行摘要?摘要行要简单得多,所以如果这是您想要的,为什么要选择没有数值的中间行呢?请再次编辑问题并澄清您想要的内容。您好,现在更新了问题(参见最后一部分,预期最终输出),这与原始问题的结果完全不同。谢谢你浪费我们的时间来帮助你。下次,在问问题之前,请先弄清楚你想要什么。有关更新的问题,请参见。@Nico首先问一个更简单的问题的问题是,它可能走错了路。这就是所谓的。让我引用该链接的开头:XY问题是询问您尝试的解决方案,而不是您的实际问题。[…]这可能会让[像我这样]试图帮助你解决问题的人感到沮丧,因为当你问起这个问题时,你需要帮助的解决方案可能与你试图解决的问题没有任何明显的联系。我正在根据@Andreas的建议编辑这个问题。。最后的结果在我的帖子上更新了。@NicoPratama你越是澄清,它就越不清楚。在我看来,在你要求其他人花时间帮助之前,你应该先弄清楚你需要什么。简单地说,我需要房子的名称和家具id作为csv的主键。因此,每个房子的每个家具都有自己的一行。即house01+家具01,house01+家具02,house01+家具03,house02+furniture01等等。@NicoPratama这将是一个很小的问题-你在哪里处理它?@michael.hor275k更新了我正在使用的xsl,我是否需要xsl分组来达到我想要的最终输出(编辑)?
Name,a,b,c,d,e,f
House01,40000,100000,160000,150000,190000,350000
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:text>Name,a,b,c,d,e,f
</xsl:text>
<xsl:apply-templates select="FirstTag/SecondTag/a/Furniture"/>
</xsl:template>
<xsl:template match="Furniture">
<xsl:variable name="pos" select="position()"/>
<xsl:value-of select="../../@Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../b/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../c/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../d/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../e/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../f/Furniture[position()=$pos]/@FURN_ID"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/FirstTag">
<!-- first pass -->
<xsl:variable name="values-rtf">
<xsl:for-each select="SecondTag/*">
<xsl:copy>
<xsl:for-each select="Furniture">
<value>
<xsl:value-of select="@FURN_AMT * @price"/>
</value>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="values" select="exsl:node-set($values-rtf)/*" />
<!-- header -->
<xsl:text>Name,</xsl:text>
<xsl:for-each select="$values">
<xsl:value-of select="name()"/>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- summary -->
<xsl:value-of select="SecondTag/@Name"/>
<xsl:text>,</xsl:text>
<xsl:for-each select="$values">
<xsl:value-of select="sum(value)"/>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>