无法生成带有标签 <Document> 的 XML 文件

Posted

技术标签:

【中文标题】无法生成带有标签 <Document> 的 XML 文件【英文标题】:Unable to generate XML file with tag <Document> 【发布时间】:2021-12-29 10:28:45 【问题描述】:

我正在尝试通过 xslt 转换从 XML 文件生成 csv 文件。 xml文件的开头:

 <?xml version="1.0" encoding="UTF-8"?>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BkToCstmrDbtCdtNtfctn>
    <GrpHdr>
            <MsgId>UPDD2021-12-20-18.26.01.660000</MsgId>
            <CreDtTm>2021-12-20T18:26:01</CreDtTm>
    </GrpHdr>
    ...
</BkToCstmrDbtCdtNtfctn>
    </Document>

转换文件:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output indent="yes" method="text"/>
<xsl:variable select="';'" name="delimiter"/>
<xsl:variable name="newline">
<xsl:text> 
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="BkToCstmrDbtCdtNtfctn/Ntfctn/Ntry/NtryDtls/TxDtls">
    <xsl:value-of select="../../../../GrpHdr/MsgId"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="../../../../Ntfctn/CreDtTm"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</Document>
</xsl:stylesheet>

但是 csv 文件并没有按预期生成,因为它看起来像这样(每条记录都在新行上):

        UPDD2021-12-20-18.26.01.660000
        2021-12-20T18:26:01
    
    
        003409153772021-12-20-18.26.01.9625
        2021-12-20T18:26:01

当我从两个文件中删除标签 Document&gt; 时,它看起来正确(添加了 ';' 并且每个都在一行上):

UPDD2021-12-20-18.26.01.660000;2021-12-20T18:26:01;

有人知道如何更新转换文件以使 csv 看起来正确吗?

问题已解决。正确转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camt="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02"
          exclude-result-prefixes="camt">
<xsl:output indent="yes" method="text"/>
<xsl:variable select="';'" name="delimiter"/>
<xsl:variable name="newline">
<xsl:text> 
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="camt:Document/camt:BkToCstmrDbtCdtNtfctn/camt:Ntfctn/camt:Ntry/camt:NtryDtls/camt:TxDtls">
    <xsl:value-of select="../../../../camt:GrpHdr/camt:MsgId"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="../../../../camt:Ntfctn/camt:CreDtTm"/>
    <xsl:value-of select="$delimiter"/>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

请展示最少但完整的 XML 输入和 XSLT 示例以及您想要的输出以及您获得的示例,以便我们理解和重现问题。您的 XSLT sn-p 与*** &lt;Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt; 然后似乎包装(尽管您没有显示任何结束标签)XSLT 代码似乎根本没有任何意义。 我已经编辑了问题 请发minimal reproducible example incl。示例输入和预期输出。 -- 提示:(1)从你的样式表中删除Document标签; (2) 请参阅此处如何处理使用默认命名空间的 XML 输入:***.com/a/34762628/3016153 【参考方案1】:

使用 XSLT 2 或 3 处理器,您要声明例如xpath-default-namespace=""urn:iso:std:iso:20022:tech:xsd:camt.054.001.02"xsl:stylesheet 元素上,然后在 XSLT 代码中编写路径,您可以在其中使用输入文档中的本地元素名称。任何xsl:template 都必须是xsl:stylesheet 的***子级。

对于 XSLT 1 处理器,您需要将命名空间 URI 绑定到 XSLT 中的前缀(例如 xmlns:camt="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02")并使用该前缀来限定路径表达式中的任何元素名称。

【讨论】:

现在生成了空文件,我补充说我是如何更改文件的 好的,现在可以了,我还得在路径中添加“camt:Document/”【参考方案2】:

如果&lt;/Document&gt; 结束标记出现在样式表的末尾(您没有向我们展示),那么您的所有 XSLT 代码都在***数据元素中,这相当于将其注释掉。结果是您在源文档上执行了“空样式表”,这将复制源文档中的文本节点并忽略其他所有内容。

【讨论】:

我已经编辑了问题以显示 XSLT 文件 - 该标签 应该在哪里打开和关闭?

以上是关于无法生成带有标签 <Document> 的 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

生成带有和不带有 HTML 标签的相同文本?

标签上带有点的字符串

无法使用 % url % 模板标签正确生成带有捕获参数的 URL

JavaWeb基础知识:JavaScript快速入门

动态生成和移除img标签---JavaScript

如何从活动标签复制文本?