2017-06-01 1 views
1

Voici mon XML:XML Expression XPath le retour des enfants avec des attributs similaires

<?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> 

Je voudrais créer une expression XPath qui sélectionneront la « partie » où le « PartNumber » avant que le/correspond à la 'InvoiceNumber' avant le /. En d'autres termes, ne conservez que la partie contenant 23456 et enlevez celles de 23459. En d'autres termes, conservez uniquement la partie contenant 23456 et enlevez les 23459. Le résultat devrait ressembler à ceci:

<?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> 

Je m'excuse d'avance pour toute terminologie incorrecte ou générale. Merci!

+0

Votre résultat ne peut être atteint via XPath seul. XPath est pour la sélection; vous avez besoin de transformation. Envisagez d'utiliser XSLT. – kjhughes

+0

Si j'utilise l'expression: /Job/Parts/Part [NuméroFrame =/Job/InvoiceNumber]/PartNumber Je peux isoler les correspondances exactes avec le 'InvoiceNumber'. Est-ce qu'il n'y a aucun moyen de l'ignorer le/et tout après? – BobTucker

+0

Bien sûr, vous pouvez utiliser 'substring-before()' pour vous aider à sélectionner les éléments 'Part' ciblés, mais avec XPath seul, vous ne pouvez pas réassembler les parties sélectionnées dans le contexte des éléments ancestraux montrés dans le résultat souhaité. – kjhughes

Répondre

0

XPath est seulement de sélectionner des éléments dans XML. Vous ne pouvez pas attendre que certains éléments soient supprimés lors de la sélection avec xpath.

XSLT doit être utilisé lorsque vous souhaitez modifier votre xml - ici dans ce cas, retirer Part étant donné que leur PartNumber rencontrer une condition spécifique.

Le xslt suivant devrait atteindre le même.

<?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> 

Les travaux xslt en utilisant XPath substring-before(PartNumber,'/') qui donne le nombre 23456 ou 23459 avant /

Ensuite, il est testé par rapport au numéro de la facture obtenue à partir XPath //Job/InvoiceNumber dans le xsl:if seulement si la condition est satisfaite, que Part est considéré.

Si vous appliquez cette xsl sur votre xml, vous obtiendrez le résultat:

<?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

Merci kjhughes & svasa. Ces réponses étaient parfaites et m'ont donné exactement ce dont j'avais besoin. – BobTucker

0

Vous pouvez sélectionner ces pièces,

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

avec cette expression XPath,

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

mais de les réassembler dans le cadre de leurs éléments ancestraux, vous aurez besoin d'aller au-delà de sélection transformation. XPath seul n'aidera pas, mais XSLT le fera.