Java类从XML阅读和写入< Group>和< Groups>元素,并且始终显示空值

camsedfj  于 2023-06-28  发布在  Java
关注(0)|答案(1)|浏览(82)

我正在创建一个类来显示XML中的数据,我需要显示用户的数据沿着他们所属的组。
下面是我得到的输出:

我正在阅读的XML具有以下结构,我试图迭代Groups > Group中的Name元素。

<?xml version="1.0" encoding="UTF-8"?>
 <users report_date="20230620">
 <user>
 <id type="integer">123456</id>
 <is-active type="boolean">true</is-active>
 <roles type="integer">2</roles>
 <name>RODRIGO BARCAT</name>
 <time-zone>America/Sao_Paulo</time-zone>
 <updated-at type="dateTime">2023-06-15T11:18:54-03:00</updated-at>
 <created-at type="dateTime">2021-10-19T10:37:42-03:00</created-at>
 <external-id nil="true"/>
 <details></details>
 <openid-url nil="true"/>
 <organization-id type="integer">123456789</organization-id>
 <notes></notes>
 <restriction-id type="integer">0</restriction-id>
 <locale-id type="integer">19</locale-id>
 <last-login type="dateTime">2023-06-15T11:18:39-03:00</last-login>
 <current-tags>TEST</current-tags>
 <email>rodrigo@test.com</email>
 <is-verified type="boolean">true</is-verified>
 <custom-role-id type="integer">1260812330129</custom-role-id>
 <groups type="array">
  <group>
  <id type="integer">1900004323624</id>
  <is-active type="boolean">true</is-active>
  <name>Grupo 1</name>
  <updated-at type="dateTime">2021-11-03T11:20:24-03:00</updated-at>
  <created-at type="dateTime">2021-11-03T11:20:24-03:00</created-at>
  <description></description>
  <is-public type="boolean">true</is-public>
</group>
<group>
  <id type="integer">5845531840667</id>
  <is-active type="boolean">true</is-active>
  <name>Grupo 2</name>
  <updated-at type="dateTime">2022-05-20T15:43:09-03:00</updated-at>
  <created-at type="dateTime">2022-05-09T12:37:24-03:00</created-at>
  <description></description>
  <is-public type="boolean">true</is-public>
</group>
<group>
  <id type="integer">1260814988809</id>
  <is-active type="boolean">true</is-active>
  <name>Grupo 3</name>
  <updated-at type="dateTime">2021-11-03T11:20:41-03:00</updated-at>
  <created-at type="dateTime">2021-11-03T11:20:41-03:00</created-at>
  <description></description>
  <is-public type="boolean">true</is-public>
</group>
<group>
  <id type="integer">6088614508699</id>
  <is-active type="boolean">true</is-active>
  <name>Grupo 4</name>
  <updated-at type="dateTime">2022-05-20T15:05:38-03:00</updated-at>
  <created-at type="dateTime">2022-05-20T15:05:38-03:00</created-at>
  <description></description>
  <is-public type="boolean">true</is-public>
</group>
<group>
  <id type="integer">1900004323564</id>
  <is-active type="boolean">true</is-active>
  <name>Grupo 5</name>
  <updated-at type="dateTime">2021-11-03T11:19:46-03:00</updated-at>
  <created-at type="dateTime">2021-11-03T11:19:46-03:00</created-at>
  <description></description>
  <is-public type="boolean">true</is-public>
</group>
</groups>
<photo-url></photo-url>
<uses-12-hour-clock>false</uses-12-hour-clock>
<phone/>
</user>
</users>

代码如下:

package com.zendesk2helix.maven.zendesk2helix_jar;

import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;

public class Usuarios {
    public static void main(String[] args) {
    String xmlFilePath = "/home/barcat/users.xml";

    try {
        // Criar um XMLInputFactory
        XMLInputFactory factory = XMLInputFactory.newInstance();

        // Criar um XMLStreamReader para o arquivo XML
        XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream(xmlFilePath));

        // Variáveis para armazenar os elementos desejados
        String id = "";
        String userName = "";
        String groupName = "";

        // Flags para controlar em qual nível estamos
        boolean insideUser = false;
        boolean insideGroup = false;

        // Loop para ler os elementos do XML
        while (reader.hasNext()) {
            int eventType = reader.next();

            if (eventType == XMLStreamConstants.START_ELEMENT) {
                String elementName = reader.getLocalName();

                // Verificar o nome do elemento
                if (elementName.equals("user")) {
                    // Entrar no elemento User
                    insideUser = true;
                } else if (elementName.equals("id") && insideUser) {
                    // Ler o ID do usuário
                    id = reader.getElementText();
                } else if (elementName.equals("name") && insideUser && !insideGroup) {
                    // Ler o nome do usuário
                    userName = reader.getElementText();
                } else if (elementName.equals("group") && insideUser) {
                    // Entrar no elemento Group
                    insideGroup = true;
                }
            } else if (eventType == XMLStreamConstants.CHARACTERS) {
                if (insideGroup) {
                    // Ler o nome do grupo
                    groupName = reader.getText();
                }
            } else if (eventType == XMLStreamConstants.END_ELEMENT) {
                String elementName = reader.getLocalName();

                // Verificar o nome do elemento final
                if (elementName.equals("user")) {
                    // Exibir os elementos lidos
                    System.out.println("ID: " + id);
                    System.out.println("User Name: " + userName);
                    System.out.println("Group Name: " + groupName);
                    System.out.println("-----------------------------");

                    // Limpar as variáveis para o próximo usuário
                    id = "";
                    userName = "";
                    groupName = "";

                    // Resetar as flags
                    insideUser = false;
                    insideGroup = false;
                }
            }
        }

        // Fechar o XMLStreamReader
        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}
jgwigjjp

jgwigjjp1#

您不会得到组输出的空值。您将得到一个仅含空格的值。
我修改了你的代码,在输出中的组名两侧放置了一个'字符,它给了我这样的输出:

ID: 1900004323564
User Name: RODRIGO BARCAT
Group Name: '
'
-----------------------------

insideGroup为true时,代码将groupName设置为遇到的字符数据的最后一个元素。这是从开始的<group>标记到结束的</user>标记。这包括在标记之间出现的纯空格字符数据。在本例中,我们得到一个换行符,因为这是空的<phone/>标记和结束的</user>标记之间的空白。
但是,您对group元素中的任何旧文本都不感兴趣。您要查找的是name元素的文本内容。为此,您需要跟踪您是否在此元素中以及是否在usergroup元素中
您需要:

  • 添加一个局部变量,用于跟踪您是否在group元素中的name元素中:
boolean insideGroupName = false;

将其与其他insideXYZ布尔变量一起添加。

  • group元素中添加一些name元素的处理,在这种情况下将此变量设置为true
} else if (elementName.equals("name") && insideGroup) {
                        insideGroupName = true;

将其添加到处理元素开始的if-else if块中。

  • 如果新的insideGroupName变量为true,则将字符事件的处理更改为仅将值读入groupName
if (insideGroupName) {
                        // Ler o nome do grupo
                        groupName = reader.getText();
                    }
  • 确保在到达相关元素的末尾时将insideGroupNameinsideGroup设置回false
if (elementName.equals("name")) {
                        insideGroupName = false;
                    } else if (elementName.equals("group")) {
                        insideGroup = false;
                    }

将其添加到处理元素结尾的块中。
我对你的代码做了这些修改,然后它给了我以下输出:

ID: 1900004323564
User Name: RODRIGO BARCAT
Group Name: Grupo 5
-----------------------------

这将在输出中为我们提供一个组名称。然而,我注意到从你的问题的顶部(强调我的):
我正在创建一个类来显示XML中的数据,我需要显示用户的数据以及他们所属的
目前为止我们只知道最后一个组名似乎你想要所有的组名。
这里的问题是在您的示例XML文件中有多个组,每次我们找到一个新的组名时,我们都会覆盖以前存储的任何值。为了解决这个问题,我们将使用List<String>来包含多个组名,而不是使用单个String值来存储单个组名。
更换管路

String groupName = "";

List<String> groupNames = new ArrayList<>();

然后,您需要将groupName的各种用法替换为groupNames的适当用法:

  • 读取组名元素中的字符数据时:将
groupName = reader.getText();

替换为

groupNames.add(reader.getText());
  • 显示读取的用户数据时:将
System.out.println("Group Name: " + groupName);

替换为

System.out.println("Group Names: " + groupNames);
  • 在显示用户详细信息后重置变量时,要为文件中的另一个用户做好准备:将
groupName = "";

替换为

groupNames.clear();

我对你的代码做了这些修改,它生成了以下输出:

ID: 1900004323564
User Name: RODRIGO BARCAT
Group Names: [Grupo 1, Grupo 2, Grupo 3, Grupo 4, Grupo 5]
-----------------------------

希望这就是你要找的。

相关问题