为 XML 指定命名空间的本地相对路径

Posted

技术标签:

【中文标题】为 XML 指定命名空间的本地相对路径【英文标题】:specify local relative path to namespace for XML 【发布时间】:2021-12-25 12:51:02 【问题描述】:

我在引用加载的 XML 文件中使用的架构文件时遇到问题。架构文件位于folder="C:\Users\zander\Desktop\20211112094529\Recipe\RECIPEs\Data\Sequences\",因为 XML 文件位于多个子文件夹中,我不想将架构文件复制到每个子文件夹中。

我找到的所有示例都与http... 位置有关,谁能帮我参考本地文件夹?

<?xml version="1.0"?>
<SEQUENCE Format="2.0" Name="hardware\bbx" xmlns="x-schema:sequence_schema.xml">
  <PASSPORT Frozen="No" Type="Production" AccessModifyGroups="All" AccessDisplayGroups="All" 
   Version="1.0" ReviseTime="28/11/2018 11:36:13.384" Revisor="Wesley" CreateTime="11/01/2012 
   17:38:14.765" Creator="Wes" Description="">
    <CUSTOM>
      <CUSTOM_PARAM Name="SendLotEndSignal" Value="0"/>
    </CUSTOM>
  </PASSPORT>
  <STEPS>
    <STEP SeqEndCleanRecipe="NO_RECIPE" Recipe="STANDARD\205C" Chambers="B2B35" SectionName="Steps">
      <CUSTOM>
        <CUSTOM_PARAM Name="Type" Value="PAAP"/>
        <CUSTOM_PARAM Name="Block" Value="B2"/>
      </CUSTOM>
    </STEP>
    <STEP SeqEndCleanRecipe="NO_RECIPE" Recipe="STANDARD\110C" Chambers="B2B14" SectionName="Steps">
      <CUSTOM>
        <CUSTOM_PARAM Name="Type" Value="PAHP"/>
        <CUSTOM_PARAM Name="Block" Value="B2"/>
      </CUSTOM>
    </STEP>
  </STEPS>
</SEQUENCE>

这是我正在使用的代码(已更新为全新代码)。当我将架构文件复制到与 XML 相同的文件夹时,代码可以完美运行,它可以正常工作,但我不想这样做,因为我有很多子文件夹:

Option Explicit

'Sub ReadAllXML(Ffolder As String)
Sub ReadAllXML()
Dim Ffolder As String

    Dim FilePath, XMLFileName, RecipeID As String
    Dim main_folder As String
    Dim oXMLFile, Recipe As Object
    Dim Col, NumberOfElements, LastRow As Long
    Dim n As Object
    Dim RecipeName, ChamberName, UnitKind, BlockName As String
    Dim strtxt, Fromtxt, FromPos, PathWithoutSequences, FirstFolder As String
    Dim wks As Worksheet
    
    'main folder is the folder where the schema file is stored
    main_folder = "C:\Users\zander\Desktop\20211112094529\Recipe\RECIPEs\Data\Sequences\"
    'Ffolder are different folders where all the XML files are stored
    Ffolder = "C:\Users\zander\Desktop\20211112094529\Recipe\RECIPEs\Data\Sequences\Subfolder1\subfolder2\"
    
    Set oXMLFile = CreateObject("Microsoft.XMLDOM")
    Set wks = ThisWorkbook.Worksheets("Sheet1")
    
    XMLFileName = Dir(Ffolder & "*.xml")
    
        If XMLFileName <> "" Then
            
            FilePath = Ffolder & XMLFileName
           ' Namespace = "xmlns=x-schema:sequence_schema.xml" "xsi:schemaLocation=""file:///C:\Users\zander\Desktop\20211112094529\Recipe\RECIPEs\Data\Sequences\sequence_schema.xml""
           
            oXMLFile.Load FilePath
            'oXMLFile.SetProperty "SelectionLanguage", "XPath"
            'oXMLFile.SetProperty "SelectionNamespaces", "xmlns=x-schema:sequence_schema.xml"
            
            'oXMLFile.resolveExternals = False
            'oXMLFile.validateOnParse = False
            
            Debug.Print oXMLFile.parseError.ErrorCode & "   " & oXMLFile.parseError.reason & "    " & oXMLFile.parseError.Line
                          
            'Set elements = oXMLFile.getElementsByTagName("STEP")
            'RecipeName = oXMLFile.SelectSingleNode("//STEP").Attributes.getNamedItem("Recipe").Text
            'BlockName = oXMLFile.SelectSingleNode("//STEP/CUSTOM").Attributes.getNamedItem("CUSTOM_PARAM").Text

            Col = 10
            NumberOfElements = oXMLFile.getElementsByTagName("STEP").Length
        
            With wks
                LastRow = wks.Cells(wks.Rows.Count, "C").End(xlUp).Row + 1
                    strtxt = FilePath
                    Fromtxt = "Sequences"
                    'Totxt = "test"
                    FromPos = InStr(strtxt, Fromtxt)
                    'ToPos = InStr(strtxt, Totxt)
                    'extract the text string between the two words
                    'ExtractStr = Mid(strtxt, FromPos + Len(Fromtxt), ToPos - FromPos - Len(Fromtxt))
         
                    PathWithoutSequences = Right(strtxt, Len(strtxt) - FromPos - 9)
                    FirstFolder = Left(PathWithoutSequences, Len(PathWithoutSequences) - Len(XMLFileName) - 1)
                    
                        .Cells(LastRow, 3) = FirstFolder
                        .Cells(LastRow, 8) = XMLFileName
                
                
                For Each n In oXMLFile.SelectNodes("//STEP")
                        RecipeName = n.Attributes.getNamedItem("Recipe").Text
                        ChamberName = n.Attributes.getNamedItem("Chambers").Text
                        UnitKind = n.ChildNodes(0).ChildNodes(0).Attributes.getNamedItem("Value").Text
                        BlockName = n.ChildNodes(0).ChildNodes(1).Attributes.getNamedItem("Value").Text
                           
                        .Cells(LastRow, Col) = RecipeName
                        .Cells(LastRow, Col + 1) = ChamberName
                        .Cells(LastRow, Col + 2) = UnitKind
                        .Cells(LastRow, Col + 3) = BlockName
                        Col = Col + 4
                 Next
             End With
                            
        End If

End Sub

【问题讨论】:

你得到什么错误? XML 解析器是否抱怨缺少“sequence_schema.xml”文件?您是否将它与 XML 放在同一个文件夹中?您可以尝试 oXMLFile.resolveExternals = false oXMLFile.validateOnParse = false。 是的,sequence_schema.xml 文件与 XML 本身不在同一个文件夹中,因此它仅在我将架构文件复制到同一个文件夹时才有效,但我想避免这种情况。我尝试添加 2 个额外的 cmets,但它不起作用。 Debug.Print XMLFileNameOVL 在即时窗口中返回什么,Dir 之后? 它返回XML文件名,结合它可以打开的文件夹路径。我使用Dir,因为最终它将遍历文件夹中的所有 XML 文件 【参考方案1】:

这里有几个关键概念:

    xmlns="x-schema:sequence_schema.xml" 不是提示 XSD 位置的方法。了解如何使用schemaLocation 以及以下 Q/A 中描述的支持材料:

    How to link XML to XSD using schemaLocation or noNamespaceSchemaLocation? Must an XML namespace name URI be retrievable? How to reference a local XML Schema file correctly? xmlns, xmlns:xsi, xsi:schemaLocation, and targetNamespace?

    您的 XPath 必须考虑默认命名空间(当前为 xmlns="x-schema:sequence_schema.xml"):请参阅此 Q/A 中的 VBA 条目,其中解释了如何在 XPath 表达式及其托管评估库/工具中指定 XML 命名空间:

    How does XPath deal with XML namespaces?

【讨论】:

嗨 kjhughes,谢谢你的链接。不幸的是,我无法让它工作。当我将SelectionLanguage 更改为XPath 时,我的节点也变得不可读。你能帮我把引用放到本地模式文件吗?架构文件的完整路径是:C:\Users\zander\Desktop\20211112094529\Recipe\RECIPEs\Data\Sequences\sequence_schema.xml 我还用我现在拥有的用于 XML 读取的完整代码更新了我的第一篇文章 @Wesley:抱歉,不,一开始有很多活动部件,我没有看到它们减少或应用我已经提供的指导的证据。 (我没有提供随机链接;这些参考资料和我的介绍性指导解决了阻碍您实现预期结果的概念缺陷。)您有责任提供minimal @987654326 @ of a single issue 每个问题,但是随着您最新的代码扩展,这是朝着错误的方向发展。 hy kjhughes,我决定通过添加一个将架构文件复制到每个文件夹的模块来解决问题。这可能不是最好的方法,但现在可以了,感谢您的帮助 解决本地架构访问问题,按照我对How to reference a local XML Schema file correctly?的回答中描述的方法进行

以上是关于为 XML 指定命名空间的本地相对路径的主要内容,如果未能解决你的问题,请参考以下文章

WebAPI 怎样获取相对路径 获取本地路径

log4j2 为 FileAppender 指定 tomcat 主目录的相对路径

如何在基于xml的spring配置中为hibernate.javax.cache.uri属性指定相对路径

tomcat映射路径的配置方法

Vue Router 相对路径转绝对路径

PHP命名空间理解