【问题标题】:I can't extract the node text with a Xpath我无法使用 Xpath 提取节点文本
【发布时间】:2018-06-08 13:47:00
【问题描述】:

我有一个这样的 XML 文件 (test.xml):

<?xml version="1.0" encoding="ISO-8859-1"?>
<s2xResponse>
  <s2xData>
    <Name>This is the name</Name>
    <InfocomData>
      <DateOfUpdate day="07" month="02" year="2018">20180207</DateOfUpdate>
      <CompanyName>MY COMPANY</CompanyName>
      <TaxCode FlagCheck="0">XXXYYYWWWZZZ</TaxCode>
    </InfocomData>
    <AssessmentSummary>
      <Rating Code="2">Rating Description for Code 2</Rating>
    </AssessmentSummary>
    <AssessmentData>
      <SectorialDistribution>
        <CompaniesNumber>11650</CompaniesNumber>
        <ScoreDistribution />
        <CervedScoreDistribution>
          <DistributionData>
            <Rating Code="1">SICUREZZA</Rating>
            <Percentage>1.91</Percentage>
          </DistributionData>
          <DistributionData>
            <Rating Code="2">SOLVIBILITA' ELEVATA</Rating>
            <Percentage>35.56</Percentage>
          </DistributionData>
        </CervedScoreDistribution>
      </SectorialDistribution>
    </AssessmentData>
  </s2xData>
</s2xResponse>

我正在尝试通过使用 XmlExtractor 的 U-SQL 脚本获取“名称”节点文本(“这是名称”)。以下是我正在使用的代码:

USE TestXML; // It contains the registered assembly

REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];

@xml = EXTRACT xml_text string
       FROM "textxpath/test.xml"
       USING Extractors.Text(rowDelimiter: "^", quoting: false);

@xml_cleaned =
    SELECT
        xml_text.Replace("\r\n", "").Replace("\t", "    ") AS xml_text
    FROM @xml;

@values =
    SELECT Microsoft.Analytics.Samples.Formats.Xml.XPath.Evaluate(xml_text, "s2xResponse/s2xData/Name")[1] AS value
    FROM @xml_cleaned;


OUTPUT @values TO @"outputs/test_xpath.txt" USING Outputters.Text(quoting: false);

但是我收到了这个运行时错误:

执行失败,出现错误“1_SV1_Extract 错误: '{"diagnosticCode":195887116,"severity":"Error","component":"RUNTIME","source":"User","errorId":"E_RUNTIME_USER_EXPRESSIONEVALUATION","message":"错误 在评估表达式时 Microsoft.Analytics.Samples.Formats.Xml.XPath.Evaluate(xml_text.Replace(\"\r\n\", \"\").替换(\"\t\", \"\"), \"s2xResponse/s2xData/Name\")[1]","description":"内部异常来自 用户表达式:索引超出范围。必须是非负数且小于 比集合的大小。

即使我对 Evaluate 结果 ([0]) 使用零索引,我也会得到相同的错误。

我的查询有什么问题?

【问题讨论】:

    标签: xpath azure-data-lake u-sql


    【解决方案1】:

    这里的问题是您将下标[1] 应用于XPath.Evaluate 的结果,我相信这将返回Name 节点。但是,您在代码中应用 [1] 下标,而不是在 XPath 中,因此下标可能从零开始,而不是像在 XPath 中那样从 1 开始,因此出现 Index out of range 错误。

    这是一种解决方案 - 只需在 Xpath 中应用下标运算符(它仍然是从 1 开始的),然后在此处选择 text()

     .Evaluate("s2xResponse/s2xData/Name[1]/text()")
    

    【讨论】:

    • 或者可能是(s2xResponse/s2xData/Name)[1]
    • Evaluate 方法(使用单个 XPath 字符串作为参数)返回一个 SqlArray,因此 [0] 索引是强制性的。我使用了这种形式:Evaluate(xml_text, "s2xResponse/s2xData/Name[1]/text()")[0],它就像一个魅力:) 我缺少的关键点是在 xpath 末尾使用 text() 。事实上,如果我使用以下形式:Evaluate(xml_text, "s2xResponse/s2xData/Name/text()")[0] 它也可以正常工作。谢谢!
    【解决方案2】:

    您是否有特殊原因要使用Evaluate 方法?我让他使用XmlDomExtractor 工作,这将允许您从 xml 中提取多个值,例如

    REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
    
    DECLARE @inputFile string = "/input/input100.xml";
    
    @input =
        EXTRACT Name string
        FROM @inputFile
        USING new Microsoft.Analytics.Samples.Formats.Xml.XmlDomExtractor(rowPath : "/s2xResponse",
              columnPaths : new SQL.MAP<string, string>{
              { "s2xData/Name", "Name" },
              }
              );
    
    
    @output =
        SELECT *
        FROM @input;
    

    【讨论】:

    • 感谢您指出这一点,@wBob!真诚地,XmlExtractor 的文档记录非常糟糕,我没有发现它包含的所有类之间的差异(XmlApplier、XmlDomExtractor、XmlExtractor、XPath)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多