XML XPath表达式返回具有相似属性的子级

时间:2017-06-01 20:17:57

标签: xml xpath expression

这是我的XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Job>
        <InvoiceNumber>23456/1.3</InvoiceNumber>
        <CompanyName>DummyJobOne</CompanyName>
        <CompanyNumber>7641</CompanyNumber>
          <Parts>
            <Part>
                <PartNumber>23456/1</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>
            <Part>
                <PartNumber>23456/2</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>             
            <Part>
                <PartNumber>23456/3.2</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>             
            <Part>
                <PartNumber>23459/1</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>
            <Part>
                <PartNumber>23459/6</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>
         </Parts>
<Job>

我想创建一个XPath表达式,它将仅选择'Part',其中'PartNumber'在/之前匹配'InvoiceNumber'之前/.// p>

换句话说,只保留包含23456的'Part'并删除23459。结果应如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Job>
        <InvoiceNumber>23456/1.3</InvoiceNumber>
        <CompanyName>DummyJobOne</CompanyName>
        <CompanyNumber>7641</CompanyNumber>
          <Parts>
            <Part>
                <PartNumber>23456/1</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>
            <Part>
                <PartNumber>23456/2</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>             
            <Part>
                <PartNumber>23456/3.2</PartNumber>
                <SourceEstimate>41847</SourceEstimate>
            </Part>             
         </Parts>
<Job>

我提前为任何不正确的术语或一般的Buffoonery道歉。 谢谢!

2 个答案:

答案 0 :(得分:0)

您可以选择这些部分,

  <Part> 
    <PartNumber>23456/1</PartNumber>  
    <SourceEstimate>41847</SourceEstimate> 
  </Part>  
  <Part> 
    <PartNumber>23456/2</PartNumber>  
    <SourceEstimate>41847</SourceEstimate> 
  </Part>  
  <Part> 
    <PartNumber>23456/3.2</PartNumber>  
    <SourceEstimate>41847</SourceEstimate> 
  </Part> 

使用此XPath表达式,

//Part[substring-before(PartNumber,'/')=substring-before(../../InvoiceNumber, '/')]

但是要在他们的祖先元素的背景下重新组装它们,你需要超越选择到转换。单独的XPath不会有帮助,但XSLT会。

答案 1 :(得分:0)

XPath仅用于选择xml中的元素。在使用xpath选择时,您不能期望删除某些元素。

如果您想要修改xml,则应使用

XSLT - 在这种情况下,请移除Part,因为PartNumber符合特定条件。

以下xslt应该实现相同的目标。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no" encoding="UTF-8" standalone="no" indent="yes"/>
 <xsl:strip-space elements="*"/>
<xsl:variable name="invoiceNumber" select="substring-before(//Job/InvoiceNumber,'/')"/>

<xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Part">
   <xsl:variable name="partNumber" select="substring-before(PartNumber,'/')"/>
   <xsl:if test="$partNumber = $invoiceNumber">
      <xsl:copy-of select="."/>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

xslt的工作方式是使用xpath substring-before(PartNumber,'/'),它在23456

之前提供数字23459/

然后根据//Job/InvoiceNumber中xpath xsl:if获取的发票号对其进行测试。只有满足条件,才会考虑Part

如果您在xml上应用此xsl,您将获得结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Job>
  <InvoiceNumber>23456/1.3</InvoiceNumber>
  <CompanyName>DummyJobOne</CompanyName>
  <CompanyNumber>7641</CompanyNumber>
  <Parts>
    <Part>
      <PartNumber>23456/1</PartNumber>
      <SourceEstimate>41847</SourceEstimate>
    </Part>
    <Part>
      <PartNumber>23456/2</PartNumber>
      <SourceEstimate>41847</SourceEstimate>
    </Part>
    <Part>
      <PartNumber>23456/3.2</PartNumber>
      <SourceEstimate>41847</SourceEstimate>
    </Part>
  </Parts>
</Job>