V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wjploop
V2EX  ›  Android

在自定义 XML 文件中引用 string 资源时,如何让 IDE 智能提示来完整输入

  •  
  •   wjploop · 2020-12-17 21:54:45 +08:00 · 8770 次点击
    这是一个创建于 1471 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单描述下需求,我需要自定义 XML 来存储一些配置信息,类似下面

    // file: cartype.xml
    
    <Car>
        <item boxId="1"  bandName="@string/xxx"  ... />
    </Car>
    

    比如,一款车子的配置信息中,牌子名称是要支持多语言的,所以使用 @string/xxx 来引用。将该文件放在 res/xml 下,解析时使用 resources.getString(@string/xxx) , 即可以获取到正确的语言文字。

    现在遇到的问题是,在自定的 xml 文件中,当输入 “@string“时,IDE 并不会提示现在有的字符串资源来让我们选择,我期望的是,能够像自定 View 中一样,输入一个定义的属性时 IDE 会有展示可选项。

    另外,该问题我也在StackOverflow提了,希望各位大佬能帮忙看看,谢谢了。

    第 1 条附言  ·  2020-12-18 17:01:32 +08:00

    整体思路是,在XSD文件中定义一个AndroidStringType,限制可选值是生成的R.classs中string。

    目前我可以为bandName做出了限制,比如限制只能输入1,2,3

      // 定义一个AndroidStringType
      <xs:simpleType name="AndroidStringType">
        <xs:restriction >
          <xs:enumeration value="1" />
          <xs:enumeration value="2" />
          <xs:enumeration value="3" />
        </xs:restriction>
      </xs:simpleType>
    
      <xs:complexType name="itemType">
        <xs:simpleContent>
          <xs:extension base="xs:string">
            <xs:attribute type="xs:string" name="boxId"/>
            // 将限制应用于目标属性bandName
            <xs:attribute type="AndroidStringType" name="bandName"/>
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>
      
    

    其限制是生效的,IDE也能够给出提示。

    现在问题转换成了,如何在XSD文件中定义一个枚举集合,包换R.class中的string字符?

    第 2 条附言  ·  2020-12-19 16:52:21 +08:00

    写完了,记录一下思路

    解析R.java文件,得到可选值集合,生成一个单独存放可选值的android_string.xsd文件,在定义的cartype.xsd用指令include进来即可,在自己定义的xml结构中能够使IDE提示可选项。

    过程中又遇到了几个问题:

    1. 如何解析R.java ?

    强调下这里是.java文件,而非.classs,刚开始懵逼地用URLClaassLoader加载这个文件,还以为自己的方式不对呢。后面使用了一个解析java文件的库, 挺有意思的库。

    另外,似乎解析string.xml文件也可以,不懂当时脑子怎么没转过来。

    1. 如何在 gradle task 中依赖maven上包?

    以前记得在buildscript下面的dependencies中添加依赖就可以了,使用classpath。这次发现,操作以上动作后,虽然已经将jar包下载到本地了,但在task中并不能引用响应的类,后来在在task中有添加dependencies{}方可正确引用。参看网上的资料,似乎都是在解释 taskA 依赖 taskB 的场景。

    1. 在xsd中如何让元素中一个属性类型依赖另一个属性值?

    由于项目中定义的xml结构,不同的数据是根据其中的attribute中一个值做区分的.

    <Car>
    <Item name = "id" value = "123"/>
    <Item name = "bandName" value = "kia"/>
    </Car>
    

    这样做的原因是解析时是处理的标签少点吧。然后我查资料处理这个问题,看到了这个XSD allow attribute only depending on other attribute value,我根据答者的方法并没有成功,IDE也启动处理1.1版本的xsd了,看了答者附带的链接,真是超出了我的理解水平。

    由于已经验证简单的xml结构能够使IDE正确提示可选项,且怀疑当前IDE可能并不完全支持xsd1.1(写了简单的测试例子也没生效),另外这样的提示方式有一个严重的不足,点击xml中的@string/xxx时期望是要跳到string.xml文件的,可是这里只能跳到定义的android_string.xsd,综上,故放弃让IDE提示输入了~

    5 条回复    2020-12-18 21:40:42 +08:00
    chenjiajia9411
        1
    chenjiajia9411  
       2020-12-18 13:40:32 +08:00
    这种情况建议自带一个 SQLite 数据库……
    liuky
        2
    liuky  
       2020-12-18 14:44:35 +08:00
    研究研究这两个东西应该可以给你带来思路
    xml schema
    xml dtd
    wjploop
        3
    wjploop  
    OP
       2020-12-18 17:10:07 +08:00
    @liuky 嗯,思路也是这样的,我在上面补充了一些实现,不过又卡在新问题上了
    liuky
        4
    liuky  
       2020-12-18 18:13:40 +08:00
    @wjploop https://blog.csdn.net/u014174328/article/details/40115743, 看看这个可以么, schema 还是在大学的时候写过
    wjploop
        5
    wjploop  
    OP
       2020-12-18 21:40:42 +08:00
    @liuky 谢谢了哈,看了,大学都在玩 schema 也是厉害啊,博客中关于为目标 element 的 attribute 添加限制我已经知道怎么写了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2797 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 03:38 · PVG 11:38 · LAX 19:38 · JFK 22:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.