如何使用可选元素解析xml

时间:2016-08-11 06:25:52

标签: c# xml postgresql xslt postgresql-9.1

SEPA ISO XML事务文件需要在ASP:.NET 4.6 MVC控制器的Postgres 9.1+中解析为平面表。

我尝试过以下代码,但这会产生错误的结果:

endaaa            tasusumma  orderinr
XX00221059842412     150.00  PV04131
XX00221059842412       0.38  PV04131

由于第二行中没有EndToEnd,因此第二行orderinr列中应该有null或空文本:

endaaa            tasusumma  orderinr
XX00221059842412     150.00  PV04131
XX00221059842412       0.38  null

如何解决这个问题?

解析可以通过其他方式完成e.q.使用xslt样式表进行转换或在客户端使用ASP.NET 4.6 MVC,如果这更合理。

create temp table t(x xml, nsa text[][]) on commit drop;
insert into t values(
'<?xml version=''1.0'' encoding=''UTF-8''?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
  <BkToCstmrStmt>
    <Stmt>
      <Acct>
        <Id>
          <IBAN>XX00221059842412</IBAN>
        </Id>
      </Acct>
      <Ntry>
        <Amt Ccy="EUR">150.00</Amt>
        <NtryDtls>
          <TxDtls>
            <Refs>
              <EndToEndId>PV04131</EndToEndId>
            </Refs>
          </TxDtls>
        </NtryDtls>
      </Ntry>
      <Ntry>
        <Amt Ccy="EUR">0.38</Amt>
        <NtryDtls>
          <TxDtls>
            <Refs>
              <AcctSvcrRef>2016080100178214-2</AcctSvcrRef>
            </Refs>
          </TxDtls>
        </NtryDtls>
      </Ntry>
    </Stmt>
  </BkToCstmrStmt>
</Document>
', ARRAY[ARRAY['ns','urn:iso:std:iso:20022:tech:xsd:camt.053.001.02']]);

SELECT 
unnest(xpath('/ns:Document/ns:BkToCstmrStmt/ns:Stmt/ns:Acct/ns:Id/ns:IBAN/text()', x,nsa))::text AS endaaa,
unnest(xpath('/ns:Document/ns:BkToCstmrStmt/ns:Stmt/ns:Ntry/ns:Amt/text()', x,nsa))::text::numeric AS tasusumma
 , unnest(xpath('/ns:Document/ns:BkToCstmrStmt/ns:Stmt/ns:Ntry/ns:NtryDtls/ns:TxDtls/ns:Refs/ns:EndToEndId/text()', x,nsa))::text AS orderinr
FROM t;

更新

使用来自Hannes的代码答案返回Postgres中的空行9.1如何使其在9.1中工作?

也发布在pgsql.general邮件列表中。

1 个答案:

答案 0 :(得分:1)

您需要首先提取所有ns:Ntry元素,然后为每个元素获取金额和EndToEndId:

listDates = new List<DateTime>();
var ven = (from Ven in DBCon.VenueSchedules
   select new
   {
      Ven.Date,
      Ven.ScheduleID,
    }).ToList();
listDates.AddRange(ven.Select(item=>Convert.ToDateTime(item.Date)).ToList());