【问题标题】:Count XML child with the same name on each parent node计算每个父节点上同名的 XML 子节点
【发布时间】:2017-11-19 17:55:33
【问题描述】:

我有以下 XML 文件:

<if:Cuerpo Renglon="1" Cantidad="13" Concepto="SOPORTE DE FARO" PUnitario="387.04" Importe="5031.52" U_x0020_de_x0020_M="PIEZA" Material="F01030106" cfdiClaveProdServ="31162504" cfdiClaveUnidad="H87" cfdiDescuento="2113.24">
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000507" />
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000874" />
  <if:Traslado CodigoMultiple="TrasladoConcepto" cfdiBase="2918.28" cfdiImpuesto="002" cfdiTipoFactor="Tasa" cfdiTasaOCuota="0.160000" cfdiImporte="466.92" />
</if:Cuerpo>
<if:Cuerpo Renglon="2" Cantidad="13" Concepto="SOPORTE DE FARO" PUnitario="387.04" Importe="5031.52" U_x0020_de_x0020_M="PIEZA" Material="F01030106" cfdiClaveProdServ="31162504" cfdiClaveUnidad="H87" cfdiDescuento="2113.24">
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
  <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
  <if:Traslado CodigoMultiple="TrasladoConcepto" cfdiBase="2918.28" cfdiImpuesto="002" cfdiTipoFactor="Tasa" cfdiTasaOCuota="0.160000" cfdiImporte="466.92" />
</if:Cuerpo>

我想计算每个if:Cuerpo父节点有多少if:Aduana节点。

例如第一个if:Cuerpo节点有4个if:Aduana子节点 第二个if:Cuerpo 节点有2 个if:Aduana 子节点。

这是完整的命名空间

  <cfdi:Addenda xmlns:if="https://www.interfactura.com/Schemas/Documentos" >
    <if:FacturaInterfactura TipoDocumentoId="0" TipoDocumento="Factura" Id="303019096">
      <if:Emisor RI="0000915" />
      <if:Receptor RI="9900136962" Activo="False" />
      <if:Encabezado IdInterno="303019096" TemplateId="78000937" Folio="928" FolioSerie="928-" SerieFolio="-928" MonedaDoc="MXN" MonedaDesc="Pesos" Status="1" CFD="True" Estatus="Por Pagar" ProcesoId="0" CondicionPago="60 días a partir entrega factu" Descuento="2113.24" SubTotal="5031.52" Total="3385.20" Moneda="MXN" LugarExpedicion="09319" TipoCambio="1.00000" TipoDocumento="Factura" metodoDePago="PUE" formaDePago="03" FolioReferencia="0740642450" RegimenFiscalEmisor="623" cfdiUsoCFDI="P01" cfdiFormaPago="03" cfdiMetodoPago="PUE" cfdiTipoRelacion="" VersionCFDI="3.3" Fecha="2017-11-18T14:15:41" cadenaOriginal="||1.1|199BEA24-32BC-4E30-8041-5DC1EADC70D8|2017-11-18T14:14:42|INT020124V62||8wyc7rDr2Vv9toCY/4ByZxrZIBYUtSycm2k6xZB5Rmgg+e5Cra1xhCArZR2w9y4K845Mr1xzxfVda6xUGie0YjKZYrlXRrhigvQ4K3EGUsFOYenDaT0DnzSIUCu8OhwBCaPsspUJzCngev6YqSPjjoCZATsvl21hljxXPuRjGjyJa8wYGUCWZzlU5ZfR65qjai9nNC0XeDyxGfZAwewbZL17RMLnH73TpPJbe7muGd1ts19EGVWCa22avj1SGBIjxJ1Dz+TPhuXk5qNI/iO5XLQWqWMUXVgnZrOSh7Gm2iR+E8Q5QV6fIytQj4g/K1EPyDJ6aD12zh4set3w+/Dn2Q==|20001000000300022323||" cadenaOriginalTimbre="||1.1|199BEA24-32BC-4E30-8041-5DC1EADC70D8|2017-11-18T14:14:42|INT020124V62||8wyc7rDr2Vv9toCY/4ByZxrZIBYUtSycm2k6xZB5Rmgg+e5Cra1xhCArZR2w9y4K845Mr1xzxfVda6xUGie0YjKZYrlXRrhigvQ4K3EGUsFOYenDaT0DnzSIUCu8OhwBCaPsspUJzCngev6YqSPjjoCZATsvl21hljxXPuRjGjyJa8wYGUCWZzlU5ZfR65qjai9nNC0XeDyxGfZAwewbZL17RMLnH73TpPJbe7muGd1ts19EGVWCa22avj1SGBIjxJ1Dz+TPhuXk5qNI/iO5XLQWqWMUXVgnZrOSh7Gm2iR+E8Q5QV6fIytQj4g/K1EPyDJ6aD12zh4set3w+/Dn2Q==|20001000000300022323||" cadenaOriginalEmisor="||3.3|928|2017-11-18T14:15:41|03|00001000000405697777|60 días a partir entrega factu|5031.52|2113.24|MXN|1.00000|3385.20|I|PUE|09319|CMC0712144R4|COMERCIALIZADORA DE MOTOCICLETAS DE CALIDAD, S.A. DE C.V.|623|PERP660325R60|PEDRO PEREYRA RABAGO|P01|31162504|13|H87|PIEZA|SOPORTE DE FARO|387.04|5031.52|2113.24|2918.28|002|Tasa|0.160000|466.92|14 51 3475 4000268|14 51 3475 4000268|14 51 3475 4000507|14 51 3475 4000874|002|Tasa|0.160000|466.92|466.92||" importeConLetra="**********************TRES MIL TRESCIENTOS OCHENTA Y CINCO PESOS 20/100 M.N.**********************">
        <if:Cuerpo Renglon="1" Cantidad="13" Concepto="SOPORTE DE FARO" PUnitario="387.04" Importe="5031.52" U_x0020_de_x0020_M="PIEZA" Material="F01030106" cfdiClaveProdServ="31162504" cfdiClaveUnidad="H87" cfdiDescuento="2113.24">
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000507" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000874" />
          <if:Traslado CodigoMultiple="TrasladoConcepto" cfdiBase="2918.28" cfdiImpuesto="002" cfdiTipoFactor="Tasa" cfdiTasaOCuota="0.160000" cfdiImporte="466.92" />
        </if:Cuerpo>
        <if:Cuerpo Renglon="2" Cantidad="13" Concepto="SOPORTE DE FARO" PUnitario="387.04" Importe="5031.52" U_x0020_de_x0020_M="PIEZA" Material="F01030106" cfdiClaveProdServ="31162504" cfdiClaveUnidad="H87" cfdiDescuento="2113.24">
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000268" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000507" />
          <if:Aduana CodigoMultiple="Aduana" PedimentoAduanero="14  51  3475  4000874" />
          <if:Traslado CodigoMultiple="TrasladoConcepto" cfdiBase="2918.28" cfdiImpuesto="002" cfdiTipoFactor="Tasa" cfdiTasaOCuota="0.160000" cfdiImporte="466.92" />
        </if:Cuerpo>
      </if:Encabezado>
    </if:FacturaInterfactura>

【问题讨论】:

  • 您能否花点时间来解释一下“我想计算每个 if:Aduana 有多少个 if:Cuerpo 或 PedimentoAduanero 每个 if:Cuerpo 有多少个”的意思?特别是“拥有每个”部分目前对我来说根本不清楚。 “1 - 4, 2 - 2”是什么意思?
  • (很高兴您顺便给我们提供了示例 XML,但为了清楚起见,我会将其简化为重要的元素和属性。)
  • 好的,我更新了问题,希望能更好地理解
  • @JonSkeet 我相信他的意思是第一个 (1) if:Cuerpo 有 4 个 if:Aduana,第二个 (2) if:Cuerpo 有 2 个 if:Aduana。
  • @aaron:可能。我希望我们能更清楚,这样我们就不必猜测了。

标签: c# xml visual-studio linq


【解决方案1】:

正如@derloopkat 所指出的,首先您需要将cfdi XML 命名空间添加到XML 文件中,并且还需要为cfdi:Addenda 添加结束标记。否则 XML 文档无效且无法处理。例如:

<cfdi:Addenda xmlns:cfdi="https://cfdi.namespace" xmlns:if="https://www.interfactura.com/Schemas/Documentos">
...
</cfdi:Addenda>

然后您可以使用XDocument 类加载XML 文件并使用Linq to XML 查询来计算if:Aduana 元素。

const string IF_NAMESPACE = "https://www.interfactura.com/Schemas/Documentos";
const string PATH_TO_XML_FILE = @"C:\path_to_xml_file.xml";

// Load XML document from file
var doc = XDocument.Load(PATH_TO_XML_FILE);

// select all if:Cuerpo elements
var cuerpoElements = doc.Descendants(XName.Get("Cuerpo", IF_NAMESPACE));

// for each if:Cuerpo element, count it's descendant if:Aduana elements
// aduanaElementsCount contains array [4, 4]
var aduanaElementsCount = cuerpoElements.Select(cuerpo => cuerpo.Descendants(XName.Get("Aduana", IF_NAMESPACE)).Count()).ToArray();

有时我更喜欢使用 XPath 查询而不是 Linq to XML,因为它有时会导致代码更短。在这种特殊情况下,它实际上有点复杂,但您仍然可以使用它来获得相同的结果:

const string IF_NAMESPACE = "https://www.interfactura.com/Schemas/Documentos";
const string PATH_TO_XML_FILE = @"C:\path_to_xml_file.xml";

XmlDocument doc = new XmlDocument();
// Load XML document from file
doc.Load(PATH_TO_XML_FILE);

// Create namespace manager for XML namespaces used in XPath query
var ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("if", IF_NAMESPACE);

var aduanaElementsCount = doc
    .SelectNodes("//if:Cuerpo", ns)// returns all if:Cuerpo nodes in XML document
    .Cast<IEnumerable>()// enables enumeration of selected nodes
    .Select(cuerpo => (cuerpo as XmlNode).SelectNodes(".//if:Aduana", ns).Count)// for each if:Cuerpo element, count it's descendant if:Aduana elements
    .ToArray();//returns array [4, 4]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多