Analisa o arquivo .xml de uma maneira específica

1

Eu tenho o seguinte .xml e quero uma saída específica:

<ContactPerson>
<GivenName>John</GivenName>
<FamilyName>Wayne</FamilyName>
<PhoneFixList>
<PhoneFix>78787878</PhoneFix>
</PhoneFixList>
<EmailList>
<Email>[email protected]</Email>
</EmailList>
</ContactPerson>

<ContactPerson>
<GivenName>James</GivenName>
<FamilyName>Stewart</FamilyName>
<PhoneFixList>
<PhoneFix>90909090</PhoneFix>
</PhoneFixList>
<EmailList>
<Email>[email protected]</Email>
</EmailList>
</ContactPerson>

Saída:

John Wayne  78787878  [email protected]
James Stewart  90909090  [email protected]

Em alguns casos, eu tenho mais de dois <ContactPerson> , então seria bom ter um ótimo loop para resolver isso. Eu tentei resolver o problema com um loop for, mas eu sempre tenho o resultado:

John Wayne  78787878  [email protected]
John Wayne  78787878  [email protected]
    
por lendoiro 09.02.2018 / 12:27

3 respostas

3

Assumindo o seguinte XML (modificado):

<?xml version="1.0"?>
<root>
  <ContactPerson>
    <GivenName>John</GivenName>
    <FamilyName>Wayne</FamilyName>
    <PhoneFixList>
      <PhoneFix>78787878</PhoneFix>
    </PhoneFixList>
    <EmailList>
      <Email>[email protected]</Email>
    </EmailList>
  </ContactPerson>
  <ContactPerson>
    <GivenName>James</GivenName>
    <FamilyName>Stewart</FamilyName>
    <PhoneFixList>
      <PhoneFix>90909090</PhoneFix>
    </PhoneFixList>
    <EmailList>
      <Email>[email protected]</Email>
    </EmailList>
  </ContactPerson>
</root>

O XMLStarlet invocação

xml sel -t -m '//ContactPerson' -v 'concat(GivenName, " ", FamilyName, " ", PhoneFixList/PhoneFix, " ", EmailList/Email)' -nl file.xml

produz

John Wayne 78787878 [email protected]
James Stewart 90909090 [email protected]

A invocação do XMLStarlet contém um loop implícito sobre todos os ContactPerson nós, e para cada um deles, os campos específicos são concatenados para produzir a saída correta. O -nl no final faz com que uma nova linha seja impressa.

    
por 09.02.2018 / 12:35
1

Com xml2 (e um shell com suporte para as citações $'...' ):

{ echo "<r>"; cat file.xml; echo "</r>"; } |
  | xml2 | 2csv -d $'\t' ContactPerson GivenName FamilyName EmailList/Email

(para ContactPerson s com mais de um endereço de e-mail, o último é retornado)

    
por 09.02.2018 / 13:53
1

Se você tiver um segundo arquivo para processá-lo, poderá criar um arquivo XSLT e usá-lo para transformar seu arquivo XML usando xsltproc .

phones.xsl :

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="ContactPerson">
  <xsl:value-of select="GivenName"/><xsl:text> </xsl:text><xsl:value-of select="FamilyName"/>
  <xsl:for-each select="PhoneFixList/PhoneFix">
    <xsl:text> </xsl:text><xsl:value-of select="."/>
  </xsl:for-each>
  <xsl:for-each select="EmailList/Email">
    <xsl:text> </xsl:text><xsl:value-of select="."/>
  </xsl:for-each>
  <xsl:text>&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>

Em seguida, transforme o arquivo (usando o XML do @Kusalananda como phones.xml ):

$ xsltproc phones.xsl phones.xml
John Wayne 78787878 [email protected]
James Stewart 90909090 [email protected]

O uso do XSLT tem a vantagem de poder fazer um loop através de elementos repetidos, fazer uma saída condicional e assim por diante. Se você está confortável com um pouco de estudo e programação, é muito poderoso.

    
por 09.02.2018 / 21:57