使用动态多个子节点将XML转换为CSV的通用XSLT转换
我正在尝试使用XSLT将xml转换为csv。我能够将数据拉入csv,但不是所有子节点。从根节点开始,csv中仅填充2级子节点。任何低于级别3的子节点都会被合并到一个节点中,并在csv中填充。 我不想在xslt中提及任何元素名称,因为xml将不断变化 使用的XML使用动态多个子节点将XML转换为CSV的通用XSLT转换,xml,csv,xslt,Xml,Csv,Xslt,我正在尝试使用XSLT将xml转换为csv。我能够将数据拉入csv,但不是所有子节点。从根节点开始,csv中仅填充2级子节点。任何低于级别3的子节点都会被合并到一个节点中,并在csv中填充。 我不想在xslt中提及任何元素名称,因为xml将不断变化 使用的XML xml <Tx> <New> <Id>123456</Id> <Submitted>true</Submitted> <Buyer&
xml <Tx>
<New>
<Id>123456</Id>
<Submitted>true</Submitted>
<Buyer>
<AcctOwnr>
<Id>
<Gender>Male</Gender>
</Id>
<City>GB</City>
</AcctOwnr>
</Buyer>
<Seller>
<AcctOwnr>
<Id>
<Gender>Female</Gender>
</Id>
<City>GB</City>
</AcctOwnr>
</Seller>
<Order>
<TrnsmssnInd>false</TrnsmssnInd>
</Order>
<Tx>
<Date>2019-05-08</Date>
<cty>DEAL</cty>
<Qty>
<Value Ccy="USD">5000</Value>
</Qty>
<Price>
<Price>
<Value>
<Amt Ccy="USD">95.1</Amt>
</Value>
</Price>
</Price>
<TradVn>XOFF</TradVn>
<CtryOfBrnch>GB</CtryOfBrnch>
</Tx>
<AddtlAttrbts>
<TxInd>false</TxInd>
</AddtlAttrbts>
</New></Tx>
xml
123456
符合事实的
预期的结果是
如果您想要一个通用转换,为给定XML中的每个文本节点和属性返回一个数据单元(都在同一行中),请尝试以下操作:
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="fruit" select="//*[text()] | //@*" />
<!-- LABELS -->
<xsl:for-each select="$fruit">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="name()" />
<xsl:text>.</xsl:text>
</xsl:for-each>
<xsl:value-of select="name()" />
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- DATA -->
<xsl:for-each select="$fruit">
<xsl:value-of select="." />
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注意,这假设检索到的数据都不包含逗号(以及其他一些假设——正如我在对您的问题的评论中提到的,真正的泛型转换很难编写) 我对上面的代码做了一些更改,我能够提取所有数据
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="fruit" select="//*[text()] | //@*" />
<!-- LABELS -->
<xsl:for-each select="$fruit">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="name()" />
<xsl:text>.</xsl:text>
</xsl:for-each>
<xsl:value-of select="name()" />
<xsl:text>,</xsl:text>
<xsl:for-each select="child::*">
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- DATA -->
<xsl:for-each select="$fruit">
<xsl:value-of select="." />
<xsl:text>,</xsl:text>
<xsl:for-each select="child::*">
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>```
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform">
.
,
,
,
,
```
请编辑您的问题,以一个最小但格式良好的XML示例开始。到目前为止,该结构的格式不正确,以
开头,以
结尾。为什么预期结果的“买方.AcctOwnr.Id.Gender”和“卖方.AcctOwnr.Id.Gender”的值都是“男性”?一般来说,如果任何第三层或更深层次的结构被重复,例如,如果你“123455654321…`,在这种情况下,您希望从XML到CSV的输出映射是什么样的?买方和卖方的性别是打字错误。期望是提取CSV中的所有节点和值,即使重复,也需要在CSV中,new.id=123456和new.id=653224在两个不同的列中。我们需要更精确的需求说明。XML能够表示比CSV更复杂的结构;XML中可能出现的一些内容很难映射到CSV,我们需要知道您希望如何处理这些情况。我们无法从一个示例中得出一般规则。thq Michael,但它只给了我第一个元素Tx.New.Id 123456否,结果就是我发布的结果-请参见:File stylesheet=New File(“C:\\style3.xsl”);文件xmlSource=新文件(“C:\\sample.xml”);DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();DocumentBuilder=factory.newDocumentBuilder();Document=builder.parse(xmlSource);StreamSource stylesource=新的StreamSource(样式表);Transformer Transformer=TransformerFactory.newInstance().newTransformer(stylesource);Source Source=新的DOMSource(文档);结果输出目标=新的StreamResult(System.out);变换器(源、输出目标)代码>我用上面的方法提取数据,恐怕我帮不了你。如果使用相同的XML输入和相同的XSLT样式表得到不同的结果,请发布一个新问题,这没有任何意义。“水果”节点没有任何子元素(至少在示例XML中没有),因此添加
部分没有任何作用。您只需要在最后一个标签和最后一个值后面加一个逗号。
Tx.New.Id,Tx.New.Submitted,Tx.New.Buyer.AcctOwnr.Id.Gender,Tx.New.Buyer.AcctOwnr.City,Tx.New.Seller.AcctOwnr.Id.Gender,Tx.New.Seller.AcctOwnr.City,Tx.New.Order.TrnsmssnInd,Tx.New.Tx.Date,Tx.New.Tx.cty,Tx.New.Tx.Qty.Value,Tx.New.Tx.Qty.Value.Ccy,Tx.New.Tx.Price.Price.Value.Amt,Tx.New.Tx.Price.Price.Value.Amt.Ccy,Tx.New.Tx.TradVn,Tx.New.Tx.CtryOfBrnch,Tx.New.AddtlAttrbts.TxInd
123456,true,Male,GB,Female,GB,false,2019-05-08,DEAL,5000,USD,95.1,USD,XOFF,GB,false
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="fruit" select="//*[text()] | //@*" />
<!-- LABELS -->
<xsl:for-each select="$fruit">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="name()" />
<xsl:text>.</xsl:text>
</xsl:for-each>
<xsl:value-of select="name()" />
<xsl:text>,</xsl:text>
<xsl:for-each select="child::*">
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- DATA -->
<xsl:for-each select="$fruit">
<xsl:value-of select="." />
<xsl:text>,</xsl:text>
<xsl:for-each select="child::*">
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>```