如何在已解析的 XML 标记值上检查 Null

Posted

技术标签:

【中文标题】如何在已解析的 XML 标记值上检查 Null【英文标题】:How to Check Null on parsed XML tags Value 【发布时间】:2013-02-24 09:06:14 【问题描述】:

目前我正在构建这个 android 应用程序,让我难过的一件事是句柄 ListView 项目全部按我需要它们的顺序显示,但如果一个标签有一个空白值,它会显示为占用单行对象除了空间和布局之外别无他物。

此图像 ListView 项目中的所有空间都是正在发送的 Null 字符串,我对其进行解析。 我只想知道处理此错误的最佳方法?

我的 ListView 项目的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

    <TextView
        android:id="@+id/ContactTitle"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Name"
        android:layout_
        android:layout_
        android:layout_alignRight="@+id/ContactTitle"
        android:layout_below="@+id/ContactTitle"
        android:layout_marginRight="17dp"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/MainPhone"
        android:layout_
        android:layout_
        android:layout_alignRight="@+id/Name"
        android:layout_below="@+id/Name"
        android:textColor="@color/White"/>

    <TextView
        android:id="@+id/Cell"
        android:layout_
        android:layout_
        android:layout_alignRight="@+id/MainPhone"
        android:layout_below="@+id/MainPhone"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Fax"
        android:layout_
        android:layout_
        android:layout_alignLeft="@+id/Cell"
        android:layout_below="@+id/Cell"
        android:textColor="@color/White" />

    <TextView
        android:id="@+id/Email"
        android:layout_
        android:layout_
        android:layout_alignLeft="@+id/Fax"
        android:layout_below="@+id/Fax"
        android:ellipsize="marquee"
        android:textColor="@color/EmailColor" />

</RelativeLayout>

我需要检查 Empty TextViews 并隐藏它们。 我的代码在这里:

protected void onPostExecute(String result) 
            String xml = result;
            String KEY_ITEM = "Contact";
            String KEY_CONTACTTITLE = "ContactTitle";
            String KEY_NAME = "Name";
            String KEY_MAINPHONE = "Phone";
            String KEY_CELLPHONE = "Cell";
            String KEY_FAX = "Fax";
            String KEY_EMAIL = "Email";
            ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

            Document doc = getDomElement(xml);
            if (xml != null) 
                
                    NodeList nl = doc.getElementsByTagName(KEY_ITEM);
                    for (int i = 0; i < nl.getLength(); i++) 
                        HashMap<String, String> map = new HashMap<String, String>();
                        Element e = (Element) nl.item(i);
                        if (getValue(e, KEY_CONTACTTITLE) != null) 
                            map.put(KEY_CONTACTTITLE,
                                    getValue(e, KEY_CONTACTTITLE));
                         else 
                            TextView contactTitle = (TextView) findViewById(R.id.ContactTitle);
                        
                        if (getValue(e, KEY_NAME) != null) 
                            map.put(KEY_NAME, getValue(e, KEY_NAME));
                        
                        if (getValue(e, KEY_MAINPHONE) != null) 
                            map.put(KEY_MAINPHONE, getValue(e, KEY_MAINPHONE));
                        

                        if (getValue(e, KEY_CELLPHONE) != null) 
                            map.put(KEY_CELLPHONE, getValue(e, KEY_CELLPHONE));
                        

                        if (getValue(e, KEY_FAX) != null) 
                            map.put(KEY_FAX, getValue(e, KEY_FAX));
                        

                        if (getValue(e, KEY_EMAIL) != null) 
                            map.put(KEY_EMAIL, getValue(e, KEY_EMAIL));
                        

                        menuItems.add(map);
                        menuItems = simple;
                    

                    String[] hashMapObjects =  KEY_CONTACTTITLE, KEY_NAME,
                            KEY_MAINPHONE, KEY_CELLPHONE, KEY_FAX, KEY_EMAIL ;
                    int[] listItemObjects =  R.id.ContactTitle, R.id.Name,
                            R.id.MainPhone, R.id.Cell, R.id.Fax, R.id.Email ;

                      ListAdapter adapter = new SimpleAdapter(
                      MoveContactsActivity.this, menuItems,
                      R.layout.listed_contacts, hashMapObjects,
                      listItemObjects);
                     setListAdapter(adapter);

我正在尝试检查该值是否为 null 以将对象添加到 HashMap。这当然不起作用,我想知道如何检查那些 null TextViews 并隐藏它们。

【问题讨论】:

请给我看看你的适配器 我正在使用简单的适配器......String[] hashMapObjects = KEY_CONTACTTITLE, KEY_NAME, KEY_MAINPHONE, KEY_CELLPHONE, KEY_FAX, KEY_EMAIL ; int[] listItemObjects = R.id.ContactTitle, R.id.Name, R.id.MainPhone, R.id.Cell, R.id.Fax, R.id.Email ; ListAdapter 适配器 = new SimpleAdapter(MoveContactsActivity.this, menuItems, R.layout.listed_contacts, hashMapObjects, listItemObjects);然后我设置适配器。 如果您希望某个列表项与另一个列表项不同,则不能使用简单适配器。您必须使用创建适配器,然后在 getView 函数上检查空值,而不是将它们设置为列表项中的任何小部件。 @William Kinaan 如果您愿意将此作为答案并提供支持它的信息,我很乐意将其作为答案。 【参考方案1】:

如果TextView 中没有可显示的内容,您只需调用View.setVisibility(View.GONE)。由于您使用的是SimpleAdapter 并且没有自定义getView 方法,因此最简单的方法是使用SimpleAdapter.ViewBinder

String[] hashMapObjects =  
        KEY_CONTACTTITLE, KEY_NAME, KEY_MAINPHONE, KEY_CELLPHONE, KEY_FAX, KEY_EMAIL 
;

int[] listItemObjects =  
        R.id.ContactTitle, R.id.Name, R.id.MainPhone, R.id.Cell, R.id.Fax, R.id.Email 
;

SimpleAdapter adapter = new SimpleAdapter(MoveContactsActivity.this, menuItems, R.layout.listed_contacts, hashMapObjects, listItemObjects);
SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() 
    @Override
    public boolean setViewValue(View view, Object object, String value) 
        if (!(view instanceof TextView)) 
            return false;
        

        final TextView text = (TextView) view;

        text.setVisibility(TextUtils.isEmpty(value) ? View.GONE : View.VISIBLE);
        text.setText(value);

        return true;
    
;

adapter.setViewBinder(binder);
setListAdapter(adapter);

【讨论】:

【参考方案2】:

我不知道你的列表视图项结构。

我的建议是:

检查标签是否为空并采取措施解决此问题,例如设置 TextView 可见性 = GONE。

【讨论】:

【参考方案3】:

正如 William 所说,如果文本为 null 或为空,您可以扩展 Simple Adapter 以添加视图的可见性:

public class MyAdapter extends SimpleAdapter 

    public MyAdapter(Context context, List<? extends Map<String, ?>> data,
            int resource, String[] from, int[] to) 
        super(context, data, resource, from, to);
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
            if(convertView!=null) //reset the visibility if a convert view is used
                convertView.setVisibility(View.VISIBLE);

        View v = super.getView(position, convertView, parent);

        //text recovering from data source. here I check the name field
        //you can add any test and hide any views using views id and setVisibility method
        String displayedText = ((HashMap<String, String>) this.getItem(position)).get("Name"); 
        if( displayedText == null || displayedText.isEmpty())
            v.setVisibility(View.GONE);


        return v;
    

使用这个类而不是 SimpleAdapter,然后你可以改变 getView 方法在你的 ListView 的任何视图的任何字段上添加条件。

获取信息:getView 返回将显示在 ListView 中给定位置的视图,您可以通过恢复给定位置的项目来根据数据源更改这些视图中的任何内容。

【讨论】:

【参考方案4】:

只需避免将空值添加到您的集合中,这些值会传递给适配器以填充列表视图

boolean elementFound = false;
for (int i = 0; i < nl.getLength(); i++) 
    HashMap<String, String> map = new HashMap<String, String>();
    Element e = (Element) nl.item(i);
    elementFound = false;
    if (getValue(e, KEY_CONTACTTITLE) != null) 
        map.put(KEY_CONTACTTITLE,
                getValue(e, KEY_CONTACTTITLE));
        elementFound = true;
     else 
        TextView contactTitle = (TextView) findViewById(R.id.ContactTitle);
    
    if (getValue(e, KEY_NAME) != null) 
        map.put(KEY_NAME, getValue(e, KEY_NAME));
        elementFound = true;
    
    if (getValue(e, KEY_MAINPHONE) != null) 
        map.put(KEY_MAINPHONE, getValue(e, KEY_MAINPHONE));
        elementFound = true;
    

    if (getValue(e, KEY_CELLPHONE) != null) 
        map.put(KEY_CELLPHONE, getValue(e, KEY_CELLPHONE));
        elementFound = true;
    

    if (getValue(e, KEY_FAX) != null) 
        map.put(KEY_FAX, getValue(e, KEY_FAX));
        elementFound = true;
    

    if (getValue(e, KEY_EMAIL) != null) 
        map.put(KEY_EMAIL, getValue(e, KEY_EMAIL));
        elementFound = true;
    
    if(elementFound)
        menuItems.add(map);
    
    //I don't understand whay are you doing this
    //menuItems = simple;

【讨论】:

【参考方案5】:

用非空的String检查你的价值也喜欢:

if (getValue(e, KEY_NAME) != null && !getValue(e,KEY_NAME).toString().equalsIgnoreCase("")) 
 map.put(KEY_NAME, getValue(e, KEY_NAME));

【讨论】:

【参考方案6】:

您正在使用SimpleAdapter。这很好,但我认为变更管理是软件的关键。您应该扩展 BaseAdapter 并处理 getView 方法。

我知道SimpleAdapter 的实施速度非常快,但是当发生变化时,它会骚扰你。如果您现在为custom adapter 再写一个文件,那么当更改到来时您会很放松。

ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();

@Override
public View getView(int position, View convertView, ViewGroup parent) 

    ViewHolder holder;
    if (convertView == null) 

        convertView = infalter.inflate(R.layout.list_row, null);
        holder = new ViewHolder();
        holder.tvRawName = (TextView) convertView
                .findViewById(R.id.tvRawName );
        holder.tvRawEmail= (TextView) convertView
                .findViewById(R.id.tvRawEmail);
        convertView.setTag(holder);

     else 
        holder = (ViewHolder) convertView.getTag();
    

    try 
         if(data.get(position).get("Email")!=null && data.get(position).get("Email").length()>0)
         
                holder.tvRawEmail.setVisibility(View.VISIBLE);
                holder.tvRawEmail.setText(data.get(position).get("Email"));
         else
         
                holder.tvRawEmail.setVisibility(View.GONE);
         

     catch (Exception e) 
        e.printStackTrace();
    

//do like for all

    return convertView;


public class ViewHolder 
    TextView tvRawName;
    TextView tvRawEmail;

【讨论】:

以上是关于如何在已解析的 XML 标记值上检查 Null的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 XML 标记字符串?

如何使用 statx 解析器识别空 xml 标记

XSLT:如何解析嵌入在 XML 标记中的 HTML

使用python如何解析XML?

如何使用 Boost ptree C++ 解析其值中包含 HTML 标记的 XML

如何在 C# 摘要中包含 html 标记,以便将其作为文本处理(不解析为 XML)?