VB.NET读取UBL电子XML发票cac:AdditionalItemProperty节点遇阻求助
提取嵌套CDATA中XML节点数据的问题
尝试读取含电子发票的XML文件,已配置命名空间,但无法提取cac:AdditionalItemProperty元素里cbc:Name值为02、cbc:Value值为2023171843的节点数据。以下是XML片段及VB.NET代码:
XML文件片段
<AttachedDocument xmlns="urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:data:specification:CoreComponentTypeSchemaModule:2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#"> <ext:UBLExtensions> ... </ext:UBLExtensions> <cbc:UBLVersionID>UBL 2.1</cbc:UBLVersionID> <cbc:CustomizationID>Doctos</cbc:CustomizationID> <cbc:ID>DT41647</cbc:ID> <cbc:IssueDate>2023-03-17</cbc:IssueDate> <cbc:ParentDocumentID>DT41647</cbc:ParentDocumentID> <cac:SenderParty> ... </cac:SenderParty> <cac:ReceiverParty> ... </cac:ReceiverParty> <cac:Attachment> <cac:ExternalReference> <cbc:MimeCode>text/xml</cbc:MimeCode> <cbc:EncodingCode>UTF-8</cbc:EncodingCode> <cbc:Description> <![CDATA[ <?xml version="1.0" encoding="UTF-8" standalone="no"?><Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sts="xxxx" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:oth="http://example.org/oth" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"><ext:UBLExtensions><ext:UBLExtension><ext:ExtensionContent> <sts:xxxExtensions><sts:InvoiceControl><sts:InvoiceAuthorization>99999999</sts:InvoiceAuthorization><sts:AuthorizationPeriod><cbc:StartDate>2023-02-23</cbc:StartDate><cbc:EndDate>2024-02-23</cbc:EndDate></sts:AuthorizationPeriod><cac:AdditionalItemProperty><cbc:Name>01</cbc:Name><cbc:Value>105584152</cbc:Value></cac:AdditionalItemProperty><cac:AdditionalItemProperty><cbc:Name>02</cbc:Name><cbc:Value>2023171843</cbc:Value></cac:AdditionalItemProperty><cac:AdditionalItemProperty><cbc:Name>03</cbc:Name><cbc:Value>184000</cbc:Value><cbc:ValueQuantity unitCode="KG">1280</cbc:ValueQuantity></cac:AdditionalItemProperty></cac:Item><cac:Price><cbc:PriceAmount currencyID="PP">184000.00</cbc:PriceAmount><cbc:BaseQuantity unitCode="94">1.00</cbc:BaseQuantity></cac:Price></cac:InvoiceLine></Invoice> ]]> </cbc:Description> </cac:ExternalReference> </cac:Attachment> <cac:ParentDocumentLineReference> </cac:ParentDocumentLineReference> </AttachedDocument>
VB.NET代码
m_xmld.Load(fileName) Dim manager As XmlNamespaceManager = New XmlNamespaceManager(m_xmld.NameTable) manager.AddNamespace("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2") manager.AddNamespace("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2") 'manager.AddNamespace("qdt", "urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2") 'manager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema") 'manager.AddNamespace("udt", "urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2") 'manager.AddNamespace("ccts", "urn:un:unece:uncefact:documentation:2") manager.AddNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2") Dim list As XmlNodeList = m_xmld.SelectNodes("//cac:Attachment//cac:ExternalReference//cbc:Description", manager) 'da resultado 2 'Dim nodeComprobante As XmlNode = m_xmld.SelectSingleNode("//cac:AdditionalItemProperty", manager) Dim nodeComprobante As XmlNode For Each Book As XmlNode In list nodeComprobante = m_xmld.SelectSingleNode("//cac:AdditionalItemProperty", manager) 'TotalXML += Book.SelectSingleNode("//cac:AdditionalItemProperty", manager).InnerXml 'error 'Dim mCodigo As Object = New Book.Attributes.GetNamedItem("Name").Value 'error Next MessageBox.Show("Tota: " & TotalXML, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
问题原因及解决方法
核心问题是目标节点位于CDATA块内部,CDATA中的内容是独立的XML文档,无法直接通过主XML的XPath查询。需要先提取CDATA内容,加载为新的XML文档后再进行查询。
修改后的VB.NET代码
m_xmld.Load(fileName) Dim manager As XmlNamespaceManager = New XmlNamespaceManager(m_xmld.NameTable) manager.AddNamespace("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2") manager.AddNamespace("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2") manager.AddNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2") Dim list As XmlNodeList = m_xmld.SelectNodes("//cac:Attachment//cac:ExternalReference//cbc:Description", manager) Dim TotalXML As String = "" For Each descNode As XmlNode In list ' 提取CDATA中的XML内容 Dim innerXmlContent As String = descNode.InnerText If Not String.IsNullOrEmpty(innerXmlContent) Then ' 加载内部XML Dim innerXmlDoc As New XmlDocument() innerXmlDoc.LoadXml(innerXmlContent) ' 为内部XML配置命名空间,注意要包含Invoice的默认命名空间 Dim innerManager As New XmlNamespaceManager(innerXmlDoc.NameTable) innerManager.AddNamespace("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2") innerManager.AddNamespace("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2") innerManager.AddNamespace("inv", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2") ' 默认命名空间 ' 查询Name为02的AdditionalItemProperty节点 Dim targetNode As XmlNode = innerXmlDoc.SelectSingleNode("//inv:Invoice//cac:AdditionalItemProperty[cbc:Name='02']", innerManager) If targetNode IsNot Nothing Then ' 获取对应的Value值 Dim valueNode As XmlNode = targetNode.SelectSingleNode("cbc:Value", innerManager) If valueNode IsNot Nothing Then TotalXML &= $"找到目标值:{valueNode.InnerText}{Environment.NewLine}" End If End If End If Next MessageBox.Show("结果: " & TotalXML, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
关键说明
- 提取
cbc:Description的InnerText获取CDATA中的完整XML内容 - 加载内部XML时,必须配置Invoice的默认命名空间(
urn:oasis:names:specification:ubl:schema:xsd:Invoice-2),否则无法查询到根节点下的内容 - 使用带条件的XPath
//inv:Invoice//cac:AdditionalItemProperty[cbc:Name='02']精准定位目标节点
内容的提问来源于stack exchange,提问作者Fernando Diaz
相关产品推荐
相关产品推荐

