Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用动态多个子节点将XML转换为CSV的通用XSLT转换_Xml_Csv_Xslt - Fatal编程技术网

使用动态多个子节点将XML转换为CSV的通用XSLT转换

使用动态多个子节点将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&

我正在尝试使用XSLT将xml转换为csv。我能够将数据拉入csv,但不是所有子节点。从根节点开始,csv中仅填充2级子节点。任何低于级别3的子节点都会被合并到一个节点中,并在csv中填充。 我不想在xslt中提及任何元素名称,因为xml将不断变化

使用的XML

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>&#10;</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>&#10;</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>&#10;</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>```