2017-06-01 86 views
1

這裏是我的XML:XML的XPath表達式返回兒童具有類似屬性

<?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表達式,將只選擇「部分」,其中/前的「零件號」相匹配的/之前的'發票號碼'。

換句話說,只保留包含23456的「部分」並刪除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> 

我提前道歉任何不正確的術語或一般滑稽。 謝謝!

+0

您的結果不能夠通過單獨的XPath實現。 XPath供選擇;你需要改造。考慮使用XSLT。 – kjhughes

+0

如果我使用表達式: /Job/Parts/Part [PartNumber =/Job/InvoiceNumber]/PartNumber,我可以將確切的匹配與「發票號」分開。有沒有辦法讓它忽略/以及之後的所有內容? – BobTucker

+0

當然,您可以使用'substring-before()'來幫助您選擇目標'Part'元素,但是單獨使用XPath,您無法在所需結果中顯示的祖先元素的上下文中重新組合所選部分。 – kjhughes

回答

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,'/')其給出之前/

然後將其針對在xsl:if只有當條件滿足從xpath的//Job/InvoiceNumber獲得的發票號測試的數目2345623459,即被認爲是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> 
+0

謝謝kjhughes&svasa。這些答案非常完美,給了我所需要的東西。 – BobTucker

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會。