0

我对使用 XSLT 非常陌生,我正在尝试将基本的 XML 文件转换为 SQL 以插入数据库。

我正在尝试转变:

<?xml version="1.0" standalone="yes"?>
<DataStore xmlns="Microsystems.D3.DataEngine">
  <DDA_Atoms>
    <ID>22d2e980-f13b-43be-83a8-4b72cd38c053</ID>
    <CONTENT />
    <NAME>name 1</NAME>
    <PREVIEW>preview 1</PREVIEW>
    <STRUCTURE_ELEMENT_ID>1</STRUCTURE_ELEMENT_ID>
    <HASH>-2013036173</HASH>
    <PATH>C:\dir1</PATH>
    <SIZE>88331</SIZE>
  </DDA_Atoms>
  <DDA_Atoms>
    <ID>4a1b0532-db0c-4790-9e71-92f6d84b4ad2</ID>
    <CONTENT />
    <NAME>Name 2</NAME>
    <PREVIEW>preview 2</PREVIEW>
    <STRUCTURE_ELEMENT_ID>2</STRUCTURE_ELEMENT_ID>
    <HASH>-1467957647</HASH>
    <PATH>C:\dir2</PATH>
    <SIZE>220557</SIZE>
  </DDA_Atoms>
</DataStore>

使用以下 XSL:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:template match="DataStore">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="DDA_Atoms">
    <xsl:text>INSERT INTO DDA_Atoms VALUES ('</xsl:text >
        <xsl:value-of select="ID"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="CONTENT"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="NAME"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="PREVIEW"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="STRUCTURE_ELEMENT_ID"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="HASH"/>
        <xsl:text>, '</xsl:text>
        <xsl:value-of select="PATH"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="SIZE"/>
        <xsl:text>)</xsl:text>
    <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

但是当我在 XML 上运行 XSL 时,它只返回节点的值,而不是文字 SQL 文本。更重要的是,它似乎实际上忽略了所有 XSL,因为当我删除所有模板匹配代码并基本上留下一个空 XSL 文档时,转换的作用完全相同:仅返回节点的所有值,如下所示:

22d2e980-f13b-43be-83a8-4b72cd38c053name 1preview 11-2013036173C:\dir1883314a1b0532-db0c-4790-9e71-92f6d84b4ad2Name 2preview 22-1467957647C:\dir2220557

我假设我的模板匹配“缺少”他们的目标或其他东西。我究竟做错了什么?

4

1 回答 1

2

问题是由于 XML 中的命名空间声明

<DataStore xmlns="Microsystems.D3.DataEngine">

这意味着这个元素,以及它的所有后代都属于这个命名空间。但是,在您的 XSLT 中没有对命名空间的引用,因此您的所有 xpath 表达式都在寻找没有命名空间的元素,并且不会匹配您的 XML。您获得文本输出仅仅是因为将使用 XSLT 的内置模板,并且这些模板将在它们找到的地方输出文本节点。

您需要做的是首先在 XSLT 中声明命名空间,并带有命名空间前缀

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
                xmlns:da="Microsystems.D3.DataEngine">

然后,无论你在哪里引用一个元素,都需要在它前面加上命名空间前缀。例如:

<xsl:template match="da:DataStore">

试试这个 XSLT

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:da="Microsystems.D3.DataEngine">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:template match="da:DataStore">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="da:DDA_Atoms">
    <xsl:text>INSERT INTO DDA_Atoms VALUES ('</xsl:text >
        <xsl:value-of select="da:ID"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:CONTENT"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:NAME"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:PREVIEW"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="da:STRUCTURE_ELEMENT_ID"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="da:HASH"/>
        <xsl:text>, '</xsl:text>
        <xsl:value-of select="da:PATH"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="da:SIZE"/>
        <xsl:text>)</xsl:text>
</xsl:template>
</xsl:stylesheet>

另请注意,第二个模板中不需要<xsl:apply-templates/>,因为无论如何您已经在处理所有子级了。

注意:如果您使用的是 XSLT 2.0,则可以使用“xpath-default-namespace”选项来声明默认命名空间。然后,您不必更改任何模板来使用名称空间前缀,因为 XSLT 会假设没有前缀的任何模板都在此默认名称空间中(而不是在没有名称空间中)。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
                xpath-default-namespace="Microsystems.D3.DataEngine">
于 2013-10-08T12:14:42.890 回答