MySQL 5.6 ExtractValue XPath 连接

MySQL 5.6 ExtractValue XPath concat

我不明白为什么 extractvalue 在使用 MySQL concat 函数时不 returns 属性值。

SET @xml = '<items>
<docHeader companyIdIssuer="company" docTypeId="2" companyIdReceiver="nin" dateIssue="2018-12-28">
    <attribute attributeId="2" value="1236"/>
    <docDetail productId="1" valor="some value">
        <variable variableId="6" value="12.3" unitId="34"/>
        <variable variableId="7" value="2.3" unitId="34"/>
        <variable variableId="3" value="4.325" unitId="34"/>
        <variable variableId="5" value="20" unitId="106"/>
        <attribute attributeId="1" value="1236"/>
    </docDetail>
</docHeader>
</items>';

SET @headerAttributePath = '//items/docHeader[1]/attribute[1]';
SET @detailPath = '//items/docHeader[1]/docDetail[1]';
SET @detailAttributePath = '//items/docHeader[1]/docDetail[1]/attribute[1]';

select  extractValue(@xml, concat(@headerAttributePath, '/@attributeId')) AS attIdConcat,
        extractValue(@xml, '//items/docHeader[1]/attribute[1]/@attributeId') AS attIdPlain,
        extractValue(@xml, concat(@headerAttributePath, '/@value')) AS attValueConcat,
        extractValue(@xml, '//items/docHeader[1]/attribute[1]/@value') AS attValuePlain,
        @headerAttributePath AS attHeaderPath,
        concat(@headerAttributePath, '/@value') AS attValuePathConcat,
        '//items/docHeader[1]/attribute[1]/@value' AS attValuePathPlain,
        STRCMP(concat(@headerAttributePath, '/@value'), '//items/docHeader[1]/attribute[1]/@value') AS pathStrComp,
        extractValue(@xml, concat(@detailPath, '/@valor')) AS detValueConcat,
        extractValue(@xml, concat(@detailAttributePath, '/@attributeId')) AS attDetIdConcat,
        extractValue(@xml, concat(@detailAttributePath, '/@value')) AS attDetValueConcat;

样本:SQL Fiddle

一个比较特殊的情况,似乎是一些路径的组合,例如items -> docHeader -> attribute -> @valueitems -> docHeader -> docDetail -> @valor,在解析时产生错误,这是一个错误。

一些解决方法:

  • 如果无法更改任何元素的名称,可以使用 CONCAT 函数中的 CAST() 函数。
  • 重命名其中一个元素,例如,docHeader 重命名为 doc_Headerattribute 重命名为 attrvalor 重命名为 _valor

db-fiddle

如@Barmar 所述,在 MySQL 8.0 中,一切都按预期工作,请参阅 db-fiddle

更新

经过一些额外的测试,我们可以看到当路径的总长度没有达到一定的字符长度时也会出现问题,参见db-fiddle