Свести XML с помощью xslt, затем импортировать в Access - PullRequest
0 голосов
/ 07 декабря 2018

Я пытался в течение 3 недель использовать файл XML в Access.Я попробовал несколько тактик, таких как преобразование в CSV и наличие связанной таблицы, но предпочел сгладить XML, а затем импортировать его с помощью VBA.Я видел много полезных примеров и многому научился, но ни один из них не позволил мне завершить работу.Я немного новичок.Это важно, я понимаю, так как мне нужно взять XML-файл большего размера, поэтому я буду приспосабливать XSLT к следующему большему файлу, вдохновленный вашей помощью.

Фрагмент XML здесь:

<?xml version="1.0" encoding="UTF-8"?>
<STOREITEMS><PRODUCT ITEM="R7876" NAME="Gloves Pair">
        <STOCK>No Stock.</STOCK></PRODUCT>
    <PRODUCT ITEM="BR122293" NAME="Silver Duo Balls">
        <STOCK>In Stock</STOCK></PRODUCT>
    <PRODUCT ITEM="cloneboyb" NAME="Cast Your Own Kit">
        <STOCK>In Stock</STOCK></PRODUCT>
    <PRODUCT ITEM="ASTRO" NAME="Astroglide">
        <STOCK>In Stock</STOCK></PRODUCT>
    <PRODUCT ITEM="3002028110" NAME="Translucence Pink">
    <STOCK>In Stock</STOCK></PRODUCT>
    <PRODUCT ITEM="0340" NAME="Cream 82g Lubricant">
        <STOCK>No Stock.</STOCK></PRODUCT>
</STOREITEMS>

Для совместимости с Access мне нужно:

<?xml version="1.0" encoding="UTF-8"?>
<STOCK>
    <PRODUCT>
        <ITEM>R7876</ITEM>
        <NAME>Gloves Pair</NAME>
        <STOCK>No Stock.</STOCK>
    </PRODUCT>
    <PRODUCT>
        <ITEM>BR122293</ITEM>
        <NAME>Silver Duo Balls</NAME>
        <STOCK>In Stock</STOCK>
    </PRODUCT>
    <PRODUCT>
        <ITEM>cloneboyb</ITEM>
        <NAME>Cast Your Own Kit</NAME>
        <STOCK>In Stock</STOCK>
    </PRODUCT>
    <PRODUCT>
        <ITEM>ASTRO</ITEM>
        <NAME>Astroglide</NAME>
        <STOCK>In Stock</STOCK>
    </PRODUCT>
    <PRODUCT>
        <ITEM>3002028110</ITEM>
        <NAME>Translucence Pink</NAME>
        <STOCK>In Stock</STOCK>
    </PRODUCT>
    <PRODUCT>
        <ITEM>0340</ITEM>
        <NAME>Cream 82g Lubricant</NAME>
        <STOCK>No Stock.</STOCK>
    </PRODUCT>
</STOCK>

Большая часть того, что я пробовал, это адаптация вещей, которые я видел здесь, поэтому я нев частности, есть отправная точка.

Сценарий VBA, который я использую для применения преобразования и импорта нового XML-файла, выглядит следующим образом:

Dim domIn As DOMDocument30
    Dim domOut As DOMDocument30
    Dim domStylesheet As DOMDocument30
    Dim xFile As String
    Dim StyleSheet As String
    Dim NewStock As String

    StyleSheet = "path to XSL"
    xFile = "path to xml"
    NewStock = "path to intended csv"
    Set domIn = New DOMDocument30

    domIn.async = False

    'Open the ADO xml document
    If domIn.Load(xFile) Then

        'Load the stylesheet
        Set domStylesheet = New DOMDocument30
        domStylesheet.Load StyleSheet

    'Apply the transform
    If Not domStylesheet Is Nothing Then
        Set domOut = New DOMDocument30
        domIn.transformNodeToObject domStylesheet, domOut

        'Save the output
        domOut.Save NewStock

        'Import the saved document into Access
        'Application.ImportXML NewStock
    End If
End If

'Cleanup
Set domIn = Nothing
Set domOut = Nothing
Set domStylesheet = Nothing

MsgBox "done!", , "ImportXMLFromADO"

Я с нетерпением жду указателей и благодарюВы заранее.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Как уже упоминалось, рассмотрим XSLT для преобразования XML в CSV.Затем, если необходимые данные должны быть сохранены в виде таблицы, сделайте MS Access импортирующим результирующий CSV-файл с DoCmd.TransferText .

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  <xsl:output method="text"/>
  <xsl:variable name="quote">&quot;</xsl:variable>

  <xsl:template match="/STOREITEMS">
      <xsl:text>"ITEM","NAME","STOCK"</xsl:text><xsl:text>&#xa;</xsl:text>
      <xsl:apply-templates select="PRODUCT"/>
  </xsl:template>

  <xsl:template match="PRODUCT">
    <xsl:value-of select="concat($quote, @ITEM, $quote, ',',
                                 $quote, @NAME, $quote, ',', 
                                 $quote, STOCK, $quote)"/>
    <xsl:if test="position()!=last()"><xsl:text>&#xa;</xsl:text></xsl:if>
  </xsl:template>

</xsl:stylesheet>

XSLT Demo

VBA (без domOut, только текст записывается в файл)

Dim domIn As New DOMDocument30, domStylesheet As New DOMDocument30
Dim xFile As String, StyleSheet As String, NewStock As String, xmlText As String
Dim fso As Object, oFile As Object

StyleSheet = "path to XSL"
xFile = "path to xml"
NewStock = "path to intended csv"

'LOAD INPUT XML
domIn.async = False
If domIn.Load(xFile) Then
    'LOAD STYLESHEET
    domStylesheet.Load StyleSheet

    'APPLY TRANSFORMATION, SAVE TO TEXT
    If Not domStylesheet Is Nothing Then
       xmlText = domIn.transformNode(domStylesheet)

       ' SAVE CSV
       Set fso = CreateObject("Scripting.FileSystemObject")
       Set oFile = fso.CreateTextFile(NewStock)
           oFile.WriteLine xmlText
       oFile.Close

       'IMPORT CSV INTO MS ACCESS
       DoCmd.TransferText acImportDelim, , "myTableName", NewStock, True, , 65001
    End If
End If

'CLEAN UP
Set domIn = Nothing: Set domStylesheet = Nothing
Set oFile = Nothing: Set fso = Nothing
0 голосов
/ 07 декабря 2018

Требуемый XSLT представляется довольно простым, просто напишите шаблон для преобразования атрибутов PRODUCT элементов в дочерние элементы и обработайте все остальное с помощью шаблона преобразования идентификаторов:

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

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="PRODUCT/@*">
      <xsl:element name="{name()}">
          <xsl:value-of select="."/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / 94hvTAm / 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...