引用XML数据库文件

时间:2015-02-09 15:28:32

标签: xml database xpath xsd

问题

假设我们在XML文件中有一些数据,例如记录人名:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persons>
     <person name="Alice" />
     <person name="Bob" />
</persons>

这些数据被认为是我们不想改变的静态数据库。

现在我们要为每个项目(此处为:person)附加一个属性。例如,我们可以存储我们之前是否遇到过这个人。当然,你可以这样做:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persons>
     <person name="Alice" met="true" />
     <person name="Bob" met="false" />
</persons>

但是,这会更改原始文件。我们想要一个引用主数据库的第二个文件,并使用附加属性对其进行扩展。

我正在寻找一种优雅,概念上令人满意(甚至是标准?)的方式来实现这一点,而不仅仅是有效的方法。以上只是一个简化的例子。

基本上,问题是如何为我们不想直接更改的现有外部XML数据库存储其他属性。

可能的方法

到目前为止,我可以想到两个选项:

  1. 天真的方式:分配UUID并使用它们来引用原始数据:

    <!-- Main file -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <persons>
         <person name="Alice" id="1234" />
         <person name="Bob" id="1235" />
    </persons>
    
    <!-- Additional data -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <attributes>
         <attr id="1234" met="true" />
         <attr id="1235" met="false" />
    </attributes>
    
  2. 在“属性”文件中保存对原始数据的XPath引用。这有意义吗?如何做到这一点?

  3. 此外,欢迎提出更好的建议。

1 个答案:

答案 0 :(得分:2)

如果您不想修改原始数据库xml,那么强制原始数据上的唯一ID将要求您完全执行您不想要的操作。但是,xpath的想法需要更多的努力才能解决深层嵌套的元素。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persons>
     <person name="Alice" />
     <person name="Bob" />
</persons>

是一个简单的例子,然后你可以通过

追加
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<attributes>
     <attr path="/persons/person[@name='Alice']" met="true" />
     <attr path="/persons/person[@name='Bob']" met="false" />
</attributes>

这非常优雅,因为您可以根据需要添加一些值。

给出了一个更复杂的例子,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service-calls>
  <companyA>
    <floor num="1">
      <error type="bsod" cause="unknown" />
    </floor>
    <floor num="1">
      <error type="bsod" cause="unknown" />
    </floor>
    <floor num="3">
      <error type="bsod" cause="unknown" />
    </floor>
  </companyA>
  <companyB>
    <floor num="2">
      <error type="bsod" cause="unknown" />
    </floor>
    <floor num="4">
      <error type="bsod" cause="unknown" />
    </floor>
    <floor num="4">
      <error type="bsod" cause="unknown" />
    </floor>
  </companyB>
</service-calls>

通过并为每个人添加一个唯一的ID是令人讨厌的。特别是当你想要的只是更新原因,并附加“状态”属性。 xpath了!对于这些,您可以获得A公司的一楼门票和B公司的四楼门票(无论出于何种原因)。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<attributes>
     <attr path="/service-calls/companyA/floor[@num='1']/error" status="fixed" 
         cause="user clicked malformed attachment" />
     <attr path="/service-calls/companyB/floor[@num='4']/error" status="replaced computer" 
         cause="malware worm" />
</attributes>

无论哪种方式,这似乎是最优雅的方法。

如果你想在地板上贴上便条,你也可以这样做:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<attributes>
     <attr path="/service-calls/companyA/floor[@num='1']" type="developers who cause trouble" /> 
     <attr path="/service-calls/companyB/floor[@num='4']" type="accounting" />
</attributes>