Выражение Xpath для зацикливания записей из разных файлов на основе идентификатора - PullRequest
0 голосов
/ 04 мая 2011

У меня есть два исходных файла

<corporations>
  <corporation>
    <CorporationID>1044293</CorporationID>
    <CorporationName>CorporationName1</CorporationName>
    <CorporationNumber>CorporationNumber1</CorporationNumber>
    <NVBusinessID>NVBusinessID1</NVBusinessID>
    <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
  </corporation>
  <corporation>
    <CorporationID>1044294</CorporationID>
    <CorporationName>CorporationName2</CorporationName>
    <CorporationNumber>CorporationNumber2</CorporationNumber>
    <NVBusinessID>NVBusinessID2</NVBusinessID>
    <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
  </corporation>
  <corporation>
    <CorporationID>1044295</CorporationID>
    <CorporationName>CorporationName3</CorporationName>
    <CorporationNumber>CorporationNumber3</CorporationNumber>
    <NVBusinessID>NVBusinessID3</NVBusinessID>
    <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
  </corporation>
</corporations>

и

<corporationActions>
  <corporationAction>
    <ActionID>5530960</ActionID>
    <CorporationID>1044293</CorporationID>
    <ActionDate>2008-05-03</ActionDate>
    <ActionType>ActionType1</ActionType>
    <ActionNotes></ActionNotes>
    <DocumentNumber>3</DocumentNumber>
    <NumberofPages>1</NumberofPages>
  </corporationAction>
  <corporationAction>
    <ActionID>5530974</ActionID>
    <CorporationID>1044294</CorporationID>
    <ActionDate>2009-05-03</ActionDate>
    <ActionType>ActionType2</ActionType>
    <ActionNotes></ActionNotes>
    <DocumentNumber>2</DocumentNumber>
    <NumberofPages>4</NumberofPages>
  </corporationAction>
  <corporationAction>
    <ActionID>5530975</ActionID>
    <CorporationID>1044294</CorporationID>
    <ActionDate>2009-05-03</ActionDate>
    <ActionType>ActionType3</ActionType>
    <ActionNotes></ActionNotes>
    <DocumentNumber>2</DocumentNumber>
    <NumberofPages>2</NumberofPages>
  </corporationAction>
  <corporationAction>
    <ActionID>5530976</ActionID>
    <CorporationID>1044295</CorporationID>
    <ActionDate>2011-05-03</ActionDate>
    <ActionType>ActionType4</ActionType>
    <ActionNotes></ActionNotes>
    <DocumentNumber>20110258778-91</DocumentNumber>
    <NumberofPages>4</NumberofPages>
  </corporationAction>
</corporationActions>

Мне нужно получить все эти записи (в качестве ответа), соответствующие CorporationID, из 1-го файла и найти соответствующие записи CorporationID (они могут быть кратны) из 2-го файла и распечатаны в следующем формате

<sendCorporationActionDetailsVariable>
 <corporationActions>
  <ns1:corporationAction>
   <ns1:NVBusinessID>NVBusinessID1</ns1:NVBusinessID>
   <ns1:CorporationName>CorporationName1</ns1:CorporationName>
   <ns1:corporationActionDetails>
    <ns1:CorporationID>1044293</ns1:CorporationID>
    <ns1:ActionDate>04/05/2008</ns1:ActionDate>
    <ns1:ActionType>Articles of Organization1</ns1:ActionType>
   </ns1:corporationActionDetails>
  </ns1:corporationAction>

  <ns1:corporationAction>
   <ns1:NVBusinessID>NVBusinessID2</ns1:NVBusinessID>
   <ns1:CorporationName>NVBusinessID2</ns1:CorporationName>
   <ns1:corporationActionDetails>
    <ns1:CorporationID>1044294</ns1:CorporationID>
    <ns1:ActionDate>04/05/2011</ns1:ActionDate>
    <ns1:ActionType>ActionType2</ns1:ActionType>
   </ns1:corporationActionDetails>
  </ns1:corporationAction>

  <ns1:corporationAction>
   <ns1:NVBusinessID>NVBusinessID2</ns1:NVBusinessID>
   <ns1:CorporationName>NVBusinessID2</ns1:CorporationName>
  <ns1:corporationActionDetails>
    <ns1:CorporationID>1044294</ns1:CorporationID>
    <ns1:ActionDate>04/05/2010</ns1:ActionDate>
    <ns1:ActionType>ActionType3</ns1:ActionType>
   </ns1:corporationActionDetails>
  </ns1:corporationAction>

  <ns1:corporationAction>
   <ns1:NVBusinessID>NVBusinessID3</ns1:NVBusinessID>
   <ns1:CorporationName>CorporationName3</ns1:CorporationName>
   <ns1:corporationActionDetails>
    <ns1:CorporationID>1044295</ns1:CorporationID>
    <ns1:ActionDate>04/05/2011</ns1:ActionDate>
    <ns1:ActionType>ActionType4</ns1:ActionType>
   </ns1:corporationActionDetails>
  </ns1:corporationAction>
 </corporationActions>
</sendCorporationActionDetailsVariable>

Вот часть файла ответов:

<ns1:corporationAction>
 <ns1:NVBusinessID>NVBusinessID2</ns1:NVBusinessID>
 <ns1:CorporationName>NVBusinessID2</ns1:CorporationName>
 <ns1:corporationActionDetails>
  <ns1:CorporationID>1044294</ns1:CorporationID>
  <ns1:ActionDate>04/05/2011</ns1:ActionDate>
  <ns1:ActionType>ActionType2</ns1:ActionType>
 </ns1:corporationActionDetails>
</ns1:corporationAction>

<ns1:corporationAction>
 <ns1:NVBusinessID>NVBusinessID2</ns1:NVBusinessID>
 <ns1:CorporationName>NVBusinessID2</ns1:CorporationName>
<ns1:corporationActionDetails>
  <ns1:CorporationID>1044294</ns1:CorporationID>
  <ns1:ActionDate>04/05/2010</ns1:ActionDate>
  <ns1:ActionType>ActionType3</ns1:ActionType>
 </ns1:corporationActionDetails>
</ns1:corporationAction>

Мне нужно, чтобы выше было в следующемформат

<ns1:corporationAction>
   <ns1:NVBusinessID>NVBusinessID2</ns1:NVBusinessID>
   <ns1:CorporationName>NVBusinessID2</ns1:CorporationName>

   <ns1:corporationActionDetails>
    <ns1:CorporationID>1044294</ns1:CorporationID>
    <ns1:ActionDate>04/05/2011</ns1:ActionDate>
    <ns1:ActionType>ActionType2</ns1:ActionType>
   </ns1:corporationActionDetails>

  <ns1:corporationActionDetails>
    <ns1:CorporationID>1044294</ns1:CorporationID>
    <ns1:ActionDate>04/05/2010</ns1:ActionDate>
    <ns1:ActionType>ActionType3</ns1:ActionType>
   </ns1:corporationActionDetails>
</ns1:corporationAction>

Я написал логику, которая просматривает for-каждого из 1-го и 2-го файла и сравнивает corporationID и печатает необходимую информацию.

<ns1:corporationActions>
  <xsl:for-each select="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction">
  <xsl:variable name="corpActPos" select="position()"/>
<xsl:for-each select="/tns:corporations/tns:corporation">
<xsl:variable name="corpPos" select="position()"/>

  <xsl:if test="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction[$corpActPos]/ns0:CorporationID = /tns:corporations/tns:corporation[$corpPos]/tns:CorporationID">
  <xsl:variable name="cntCorpId" select="count($InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction/ns0:CorporationID)"/>
    <ns1:corporationAction>
      <ns1:NVBusinessID>
        <xsl:value-of select="/tns:corporations/tns:corporation[$corpPos]/tns:NVBusinessID"/>
      </ns1:NVBusinessID>

<xsl:for-each select="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction[$corpActPos]/ns0:CorporationID">

  <ns1:corporationActionDetails>
        <ns1:CorporationID>
          <xsl:value-of select="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction[$corpActPos]/ns0:CorporationID"/>
        </ns1:CorporationID>
        <ns1:ActionDate>
          <xsl:value-of select="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction[$corpActPos]/ns0:ActionDate"/>
        </ns1:ActionDate>
        <ns1:ActionType>
          <xsl:value-of select="$InvokeCorpActFileReaderOutputVariable.body/ns0:corporationActions/ns0:corporationAction[$corpActPos]/ns0:ActionType"/>
        </ns1:ActionType>
  </ns1:corporationActionDetails>

</xsl:for-each>
    </ns1:corporationAction>
    </xsl:if>
  </xsl:for-each>
  </xsl:for-each>
</ns1:corporationActions>

Вместо этого янужно одно выражение XPATH, которое позаботится об этом.

1 Ответ

0 голосов
/ 04 мая 2011

Требуемый вывод не может быть получен только в результате вычисления одного выражения XPath. XPath - это язык запросов для документов XML, и поэтому оценка выражения XPath никогда не изменяет структуру любого документа XML и никогда не изменяет ни один узел в любом документе XML.

Требуется изменить узлы (например, новые узлы находятся в новом пространстве имен - к которому привязан префикс ns1:) - этого нельзя сделать, просто оценивая выражение XPath.

Для выполнения таких преобразований вам нужен не только XPath, но и другой язык, на котором размещается движок XPath - например, XSLT, XQuery или любой язык программирования с DOM API.

Такое преобразование можно записать очень компактным способом, используя XSLT:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns1="my:ns1" exclude-result-prefixes="ns1" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="ActionByCorpId" match="corporationAction"
  use="CorporationID"/>

 <xsl:variable name="vDoc2" select="document('delete16.xml')"/>

 <xsl:template match="/">

  <sendCorporationActionDetailsVariable>
   <corporationActions>
    <xsl:apply-templates select="/*/*/CorporationID"/>
   </corporationActions>
  </sendCorporationActionDetailsVariable>
 </xsl:template>

 <xsl:template match="CorporationID">
   <xsl:variable name="vId" select="."/>

   <xsl:for-each select="$vDoc2/*">
     <xsl:apply-templates mode="addNamespace"
      select="key('ActionByCorpId',$vId)"/>
   </xsl:for-each>
 </xsl:template>

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

 <xsl:template match="*" mode="addNamespace">
  <xsl:element name="ns1:{name()}" namespace="my:ns1">
   <xsl:apply-templates select="node()|@*" mode="addNamespace"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML :

<corporations>
    <corporation>
        <CorporationID>1044293</CorporationID>
        <CorporationName>CorporationName1</CorporationName>
        <CorporationNumber>CorporationNumber1</CorporationNumber>
        <NVBusinessID>NVBusinessID1</NVBusinessID>
        <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
    </corporation>
    <corporation>
        <CorporationID>1044294</CorporationID>
        <CorporationName>CorporationName2</CorporationName>
        <CorporationNumber>CorporationNumber2</CorporationNumber>
        <NVBusinessID>NVBusinessID2</NVBusinessID>
        <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
    </corporation>
    <corporation>
        <CorporationID>1044295</CorporationID>
        <CorporationName>CorporationName3</CorporationName>
        <CorporationNumber>CorporationNumber3</CorporationNumber>
        <NVBusinessID>NVBusinessID3</NVBusinessID>
        <BusinessLicenseExp>2011-04-05T12:12:12</BusinessLicenseExp>
    </corporation>
</corporations>

желаемый, правильный результат получается :

<sendCorporationActionDetailsVariable>
   <corporationActions>
      <ns1:corporationAction xmlns:ns1="my:ns1">
         <ns1:ActionID>5530960</ns1:ActionID>
         <ns1:CorporationID>1044293</ns1:CorporationID>
         <ns1:ActionDate>2008-05-03</ns1:ActionDate>
         <ns1:ActionType>ActionType1</ns1:ActionType>
         <ns1:ActionNotes/>
         <ns1:DocumentNumber>3</ns1:DocumentNumber>
         <ns1:NumberofPages>1</ns1:NumberofPages>
      </ns1:corporationAction>
      <ns1:corporationAction xmlns:ns1="my:ns1">
         <ns1:ActionID>5530974</ns1:ActionID>
         <ns1:CorporationID>1044294</ns1:CorporationID>
         <ns1:ActionDate>2009-05-03</ns1:ActionDate>
         <ns1:ActionType>ActionType2</ns1:ActionType>
         <ns1:ActionNotes/>
         <ns1:DocumentNumber>2</ns1:DocumentNumber>
         <ns1:NumberofPages>4</ns1:NumberofPages>
      </ns1:corporationAction>
      <ns1:corporationAction xmlns:ns1="my:ns1">
         <ns1:ActionID>5530975</ns1:ActionID>
         <ns1:CorporationID>1044294</ns1:CorporationID>
         <ns1:ActionDate>2009-05-03</ns1:ActionDate>
         <ns1:ActionType>ActionType3</ns1:ActionType>
         <ns1:ActionNotes/>
         <ns1:DocumentNumber>2</ns1:DocumentNumber>
         <ns1:NumberofPages>2</ns1:NumberofPages>
      </ns1:corporationAction>
      <ns1:corporationAction xmlns:ns1="my:ns1">
         <ns1:ActionID>5530976</ns1:ActionID>
         <ns1:CorporationID>1044295</ns1:CorporationID>
         <ns1:ActionDate>2011-05-03</ns1:ActionDate>
         <ns1:ActionType>ActionType4</ns1:ActionType>
         <ns1:ActionNotes/>
         <ns1:DocumentNumber>20110258778-91</ns1:DocumentNumber>
         <ns1:NumberofPages>4</ns1:NumberofPages>
      </ns1:corporationAction>
   </corporationActions>
</sendCorporationActionDetailsVariable>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...